File Coverage

blib/lib/IO/K8s/Role/SpecBuilder.pm
Criterion Covered Total %
statement 63 101 62.3
branch 26 66 39.3
condition 6 30 20.0
subroutine 7 8 87.5
pod 0 5 0.0
total 102 210 48.5


line stmt bran cond sub pod time code
1             package IO::K8s::Role::SpecBuilder;
2             # ABSTRACT: Role for deep-path spec manipulation on CRD objects
3             our $VERSION = '1.008';
4 14     14   9555 use Moo::Role;
  14         31  
  14         167  
5 14     14   8676 use Scalar::Util qw(looks_like_number);
  14         55  
  14         22547  
6              
7             sub _walk_path {
8 0     0   0 my ($data, $path, $vivify) = @_;
9 0         0 my @parts = split /\./, $path;
10 0         0 my $last_key = pop @parts;
11 0         0 my $current = $data;
12              
13 0         0 for my $part (@parts) {
14 0 0 0     0 if (ref $current eq 'ARRAY' && $part =~ /^\d+$/) {
    0          
15 0 0 0     0 if ($vivify && !defined $current->[$part]) {
16 0         0 $current->[$part] = {};
17             }
18 0         0 $current = $current->[$part];
19             } elsif (ref $current eq 'HASH') {
20 0 0 0     0 if ($vivify && !defined $current->{$part}) {
21             # Look ahead: if next step is numeric, create array
22 0         0 my $idx = 0;
23 0         0 for my $p (@parts, $last_key) {
24 0 0       0 last if $p eq $part;
25 0         0 $idx++;
26             }
27 0         0 $current->{$part} = {};
28             }
29 0         0 $current = $current->{$part};
30             } else {
31 0 0       0 return (undef, undef) unless $vivify;
32 0         0 return (undef, undef);
33             }
34             }
35              
36 0         0 return ($current, $last_key);
37             }
38              
39             sub spec_get {
40 26     26 0 432447 my ($self, $path) = @_;
41 26         919 my $spec = $self->spec;
42 26 100       287 return undef unless ref $spec eq 'HASH';
43              
44 25         84 my @parts = split /\./, $path;
45 25         45 my $current = $spec;
46              
47 25         60 for my $part (@parts) {
48 43 100 66     187 if (ref $current eq 'ARRAY' && $part =~ /^\d+$/) {
    50          
49 6         18 $current = $current->[$part];
50             } elsif (ref $current eq 'HASH') {
51 37         108 $current = $current->{$part};
52             } else {
53 0         0 return undef;
54             }
55 43 100       166 return undef unless defined $current;
56             }
57              
58 21         176 return $current;
59             }
60              
61             sub spec_set {
62 5     5 0 14348 my ($self, $path, $value) = @_;
63 5         153 my $spec = $self->spec;
64 5 100       45 unless (ref $spec eq 'HASH') {
65 1         3 $spec = {};
66 1         27 $self->spec($spec);
67             }
68              
69 5         52 my @parts = split /\./, $path;
70 5         11 my $last_key = pop @parts;
71 5         12 my $current = $spec;
72              
73 5         14 for my $part (@parts) {
74 2 50 33     14 if (ref $current eq 'ARRAY' && $part =~ /^\d+$/) {
    50          
75 0 0       0 $current->[$part] = {} unless ref $current->[$part];
76 0         0 $current = $current->[$part];
77             } elsif (ref $current eq 'HASH') {
78 2 50       10 $current->{$part} = {} unless ref $current->{$part};
79 2         7 $current = $current->{$part};
80             }
81             }
82              
83 5 50 33     28 if (ref $current eq 'ARRAY' && $last_key =~ /^\d+$/) {
    50          
84 0         0 $current->[$last_key] = $value;
85             } elsif (ref $current eq 'HASH') {
86 5         15 $current->{$last_key} = $value;
87             }
88              
89 5         20 return $self;
90             }
91              
92             sub spec_push {
93 3     3 0 14396 my ($self, $path, @values) = @_;
94 3         139 my $spec = $self->spec;
95 3 50       36 unless (ref $spec eq 'HASH') {
96 0         0 $spec = {};
97 0         0 $self->spec($spec);
98             }
99              
100 3         64 my @parts = split /\./, $path;
101 3         11 my $last_key = pop @parts;
102 3         6 my $current = $spec;
103              
104 3         10 for my $part (@parts) {
105 0 0 0     0 if (ref $current eq 'ARRAY' && $part =~ /^\d+$/) {
    0          
106 0 0       0 $current->[$part] = {} unless ref $current->[$part];
107 0         0 $current = $current->[$part];
108             } elsif (ref $current eq 'HASH') {
109 0 0       0 $current->{$part} = {} unless ref $current->{$part};
110 0         0 $current = $current->{$part};
111             }
112             }
113              
114 3 50 33     20 if (ref $current eq 'ARRAY' && $last_key =~ /^\d+$/) {
    50          
115 0 0       0 $current->[$last_key] = [] unless ref $current->[$last_key] eq 'ARRAY';
116 0         0 push @{$current->[$last_key]}, @values;
  0         0  
117             } elsif (ref $current eq 'HASH') {
118 3 100       14 $current->{$last_key} = [] unless ref $current->{$last_key} eq 'ARRAY';
119 3         6 push @{$current->{$last_key}}, @values;
  3         10  
120             }
121              
122 3         12 return $self;
123             }
124              
125             sub spec_merge {
126 1     1 0 6091 my ($self, %data) = @_;
127 1         32 my $spec = $self->spec;
128 1 50       11 unless (ref $spec eq 'HASH') {
129 0         0 $spec = {};
130 0         0 $self->spec($spec);
131             }
132 1         4 @{$spec}{keys %data} = values %data;
  1         3  
133 1         5 return $self;
134             }
135              
136             sub spec_delete {
137 4     4 0 16400 my ($self, $path) = @_;
138 4         127 my $spec = $self->spec;
139 4 50       40 return $self unless ref $spec eq 'HASH';
140              
141 4         23 my @parts = split /\./, $path;
142 4         10 my $last_key = pop @parts;
143 4         8 my $current = $spec;
144              
145 4         13 for my $part (@parts) {
146 2 50 33     15 if (ref $current eq 'ARRAY' && $part =~ /^\d+$/) {
    50          
147 0         0 $current = $current->[$part];
148             } elsif (ref $current eq 'HASH') {
149 2         4 $current = $current->{$part};
150             } else {
151 0         0 return $self;
152             }
153 2 100       12 return $self unless defined $current;
154             }
155              
156 3 50 0     12 if (ref $current eq 'HASH') {
    0          
157 3         11 delete $current->{$last_key};
158             } elsif (ref $current eq 'ARRAY' && $last_key =~ /^\d+$/) {
159 0         0 splice @$current, $last_key, 1;
160             }
161              
162 3         11 return $self;
163             }
164              
165             1;
166              
167             __END__