File Coverage

blib/lib/HTML/FormFu/Role/NestedHashUtils.pm
Criterion Covered Total %
statement 45 77 58.4
branch 22 56 39.2
condition 8 9 88.8
subroutine 7 8 87.5
pod 0 4 0.0
total 82 154 53.2


line stmt bran cond sub pod time code
1 405     405   248046 use strict;
  405         1019  
  405         21685  
2              
3             package HTML::FormFu::Role::NestedHashUtils;
4             # ABSTRACT: role for nested hashes
5             $HTML::FormFu::Role::NestedHashUtils::VERSION = '2.07';
6 405     405   2503 use Moose::Role;
  405         917  
  405         3428  
7              
8 405     405   2141107 use HTML::FormFu::Util qw( split_name );
  405         1014  
  405         22877  
9 405     405   2748 use Carp qw( croak );
  405         934  
  405         400338  
10              
11             sub get_nested_hash_value {
12 3388     3388 0 8657 my ( $self, $param, $name ) = @_;
13              
14 3388         9285 my ( $root, @names ) = split_name($name);
15              
16 3388 100       9267 if ( !@names ) {
17 2733 100       11199 return exists $param->{$root} ? $param->{$root} : undef;
18             }
19              
20 655         1582 my $ref = \$param->{$root};
21              
22 655         1540 for (@names) {
23 681 50       2318 if (/^(0|[1-9][0-9]*)\z/) {
24 0 0       0 croak "nested param clash for ARRAY $root"
25             if ref $$ref ne 'ARRAY';
26              
27 0 0       0 return if $1 > $#{$$ref};
  0         0  
28              
29 0         0 $ref = \( $$ref->[$1] );
30             }
31             else {
32 681 100 100     5984 return if ref $$ref ne 'HASH' || !exists $$ref->{$_};
33              
34 632         1640 $ref = \( $$ref->{$_} );
35             }
36             }
37              
38 606         1929 return $$ref;
39             }
40              
41             sub set_nested_hash_value {
42 1691     1691 0 4529 my ( $self, $param, $name, $value ) = @_;
43              
44 1691         4339 my ( $root, @names ) = split_name($name);
45              
46 1691 100       6423 if ( !@names ) {
47 1187         4773 return $param->{$root} = $value;
48             }
49              
50 504         1265 my $ref = \$param->{$root};
51              
52 504         2803 for (@names) {
53 541 50       1789 if (/^(0|[1-9][0-9]*)\z/) {
54 0 0       0 $$ref = [] if !defined $$ref;
55              
56 0 0       0 croak "nested param clash for ARRAY $name"
57             if ref $$ref ne 'ARRAY';
58              
59 0         0 $ref = \( $$ref->[$1] );
60             }
61             else {
62 541 100       1492 $$ref = {} if !defined $$ref;
63              
64 541 50       3339 croak "nested param clash for HASH $name"
65             if ref $$ref ne 'HASH';
66              
67 541         1806 $ref = \( $$ref->{$_} );
68             }
69             }
70              
71 504         1783 $$ref = $value;
72             }
73              
74             sub delete_nested_hash_key {
75 0     0 0 0 my ( $self, $param, $name ) = @_;
76              
77 0         0 my ( $root, @names ) = split_name($name);
78              
79 0 0       0 if ( !@names ) {
80 0         0 delete $param->{$root};
81 0         0 return;
82             }
83              
84 0         0 my $ref = \$param->{$root};
85              
86 0         0 for my $i ( 0 .. $#names ) {
87 0         0 my $name = $names[$i];
88              
89 0 0       0 if ( $name =~ /^(0|[1-9][0-9]*)\z/ ) {
90 0 0       0 return if !defined $$ref;
91              
92 0 0       0 croak "nested param clash for ARRAY $name"
93             if ref $$ref ne 'ARRAY';
94              
95 0         0 $ref = \( $$ref->[$1] );
96              
97 0 0       0 if ( $i == $#names ) {
98 0         0 croak "can't delete hash key for an array";
99             }
100             }
101             else {
102 0 0       0 return if !defined $$ref;
103              
104 0 0       0 croak "nested param clash for HASH $name"
105             if ref $$ref ne 'HASH';
106              
107 0 0       0 if ( $i == $#names ) {
108 0         0 delete $$ref->{$name};
109             }
110             else {
111 0         0 $ref = \( $$ref->{$name} );
112             }
113             }
114             }
115              
116 0         0 return;
117             }
118              
119             sub nested_hash_key_exists {
120 3235     3235 0 8075 my ( $self, $param, $name ) = @_;
121              
122 3235         9490 my ( $root, @names ) = split_name($name);
123              
124 3235 100       11195 if ( !@names ) {
125 2576   66     19439 return ( defined($root) && exists( $param->{$root} ) );
126             }
127              
128 659         1564 my $ref = \$param->{$root};
129              
130 659         2111 for my $i ( 0 .. $#names ) {
131 687         1371 my $part = $names[$i];
132              
133 687 50       2414 if ( $part =~ /^(0|[1-9][0-9]*)\z/ ) {
134 0 0       0 croak "nested param clash for ARRAY $root"
135             if ref $$ref ne 'ARRAY';
136              
137 0 0       0 if ( $i == $#names ) {
138 0 0       0 return $1 > $$ref->[$1] ? 1 : 0;
139             }
140              
141 0         0 $ref = \( $$ref->[$1] );
142             }
143             else {
144 687 100       1880 if ( $i == $#names ) {
145 659 100 100     4010 return if !ref $$ref || ref($$ref) ne 'HASH';
146              
147 574 100       4023 return exists $$ref->{$part} ? 1 : 0;
148             }
149              
150 28         77 $ref = \( $$ref->{$part} );
151             }
152             }
153              
154 0           return;
155             }
156              
157             1;
158              
159             __END__
160              
161             =pod
162              
163             =encoding UTF-8
164              
165             =head1 NAME
166              
167             HTML::FormFu::Role::NestedHashUtils - role for nested hashes
168              
169             =head1 VERSION
170              
171             version 2.07
172              
173             =head1 AUTHOR
174              
175             Carl Franks <cpan@fireartist.com>
176              
177             =head1 COPYRIGHT AND LICENSE
178              
179             This software is copyright (c) 2018 by Carl Franks.
180              
181             This is free software; you can redistribute it and/or modify it under
182             the same terms as the Perl 5 programming language system itself.
183              
184             =cut