File Coverage

blib/lib/JSON_File.pm
Criterion Covered Total %
statement 72 121 59.5
branch 18 44 40.9
condition n/a
subroutine 21 31 67.7
pod 0 6 0.0
total 111 202 54.9


line stmt bran cond sub pod time code
1             package JSON_File;
2             BEGIN {
3 1     1   90998 $JSON_File::AUTHORITY = 'cpan:GETTY';
4             }
5             {
6             $JSON_File::VERSION = '0.003';
7             }
8             # ABSTRACT: Tie a hash or an array to a JSON
9              
10 1     1   2440 use Moo;
  1         29791  
  1         7  
11 1     1   2649 use JSON::MaybeXS;
  1         8  
  1         76  
12 1     1   1419 use Path::Class;
  1         42375  
  1         78  
13 1     1   1970 use autodie;
  1         21773  
  1         6  
14              
15             has json => (
16             is => 'ro',
17             lazy => 1,
18             default => sub {
19             my $self = shift;
20             my $json = JSON->new()->utf8(1)->canonical(1);
21             $json = $json->convert_blessed($self->convert_blessed) if $self->has_convert_blessed;
22             $json = $json->allow_blessed($self->allow_blessed) if $self->has_allow_blessed;
23             $json = $json->allow_unknown($self->allow_unknown) if $self->has_allow_unknown;
24             $json = $json->pretty($self->pretty) if $self->has_pretty;
25             return $json;
26             },
27             );
28              
29             has pretty => (
30             is => 'ro',
31             lazy => 1,
32             predicate => 1,
33             );
34              
35             has allow_unknown => (
36             is => 'ro',
37             lazy => 1,
38             predicate => 1,
39             );
40              
41             has allow_blessed => (
42             is => 'ro',
43             lazy => 1,
44             predicate => 1,
45             );
46              
47             has convert_blessed => (
48             is => 'ro',
49             lazy => 1,
50             predicate => 1,
51             );
52              
53             has filename => (
54             is => 'ro',
55             required => 1,
56             );
57              
58             has abs_filename => (
59             is => 'ro',
60             lazy => 1,
61             default => sub { file(shift->filename)->absolute },
62             );
63              
64             has tied => (
65             is => 'ro',
66             required => 1,
67             );
68              
69             sub BUILD {
70 6     6 0 6398 my ( $self ) = @_;
71 6         159 $self->abs_filename;
72             }
73              
74             sub data {
75 77     77 0 103 my ( $self ) = @_;
76 77 50       1746 if (-f $self->abs_filename) {
77 77         16891 return $self->load_file;
78             } else {
79 0 0       0 if ($self->tied eq 'HASH') {
    0          
80 0         0 return {};
81             } elsif ($self->tied eq 'ARRAY') {
82 0         0 return [];
83             }
84             }
85             }
86              
87             sub add_data {
88 12     12 0 25 my ( $self, $key, $value ) = @_;
89 12         33 my $data = $self->data;
90 12 100       2032 if ($self->tied eq 'HASH') {
    50          
91 4         14 $data->{$key} = $value;
92             } elsif ($self->tied eq 'ARRAY') {
93 8         17 $data->[$key] = $value;
94             }
95 12         36 $self->save_file($data);
96             }
97              
98             sub remove_data {
99 0     0 0 0 my ( $self, $key, $value ) = @_;
100 0         0 my $data = $self->data;
101 0 0       0 if ($self->tied eq 'HASH') {
    0          
102 0         0 delete $data->{$key};
103             } elsif ($self->tied eq 'ARRAY') {
104 0         0 delete $data->[$key];
105             }
106 0         0 $self->save_file($data);
107             }
108              
109             sub load_file {
110 77     77 0 106 my ( $self ) = @_;
111 77         214 local $/;
112 77         2117 open( my $fh, '<', $self->abs_filename );
113 77         21217 my $json_text = <$fh>;
114 77         2120 return $self->json->decode( $json_text );
115             }
116              
117             sub save_file {
118 15     15 0 24 my ( $self, $data ) = @_;
119 15         43 local $/;
120 15         373 open( my $fh, '>', $self->abs_filename );
121 15         9020 my $json_text = $self->json->encode( $data );
122 15         231 print $fh $json_text;
123 15         52 close($fh);
124             }
125              
126             sub TIEHASH {shift->new(
127 4     4   13762 filename => shift,
128             tied => 'HASH',
129             @_,
130             )}
131              
132             sub TIEARRAY {shift->new(
133 2     2   2358 filename => shift,
134             tied => 'ARRAY',
135             @_,
136             )}
137              
138             sub FETCH {
139 32     32   1348 my ( $self, $key ) = @_;
140 32 100       118 if ($self->tied eq 'HASH') {
    50          
141 16         27 return $self->data->{$key};
142             } elsif ($self->tied eq 'ARRAY') {
143 16         30 return $self->data->[$key];
144             }
145             }
146              
147             sub STORE {
148 12     12   4030 my ( $self, $key, $value ) = @_;
149 12         94 $self->add_data($key,$value);
150             }
151              
152             sub FETCHSIZE {
153 11     11   849 my ( $self ) = @_;
154 11         13 return scalar @{$self->data};
  11         21  
155             }
156              
157             sub PUSH {
158 0     0   0 my ( $self, @values ) = @_;
159 0         0 my @array = @{$self->data};
  0         0  
160 0         0 push @array, @values;
161 0         0 $self->save_file(\@array);
162             }
163              
164             sub UNSHIFT {
165 0     0   0 my ( $self, @values ) = @_;
166 0         0 my @array = @{$self->data};
  0         0  
167 0         0 unshift @array, @values;
168 0         0 $self->save_file(\@array);
169             }
170              
171             sub POP {
172 0     0   0 my ( $self ) = @_;
173 0         0 my @array = @{$self->data};
  0         0  
174 0         0 my $value = pop @array;
175 0         0 $self->save_file(\@array);
176 0         0 return $value;
177             }
178              
179             sub SHIFT {
180 0     0   0 my ( $self ) = @_;
181 0         0 my @array = @{$self->data};
  0         0  
182 0         0 my $value = shift @array;
183 0         0 $self->save_file(\@array);
184 0         0 return $value;
185             }
186              
187             sub SPLICE {
188 0     0   0 my $self = shift;
189 0         0 return splice(@{$self->data},@_);
  0         0  
190             }
191              
192             sub DELETE {
193 0     0   0 my ( $self, $key ) = @_;
194 0         0 $self->remove_data($key)
195             }
196              
197             sub EXISTS {
198 4     4   496 my ( $self, $key ) = @_;
199 4 50       16 if ($self->tied eq 'HASH') {
    0          
200 4         13 return exists $self->data->{$key};
201             } elsif ($self->tied eq 'ARRAY') {
202 0         0 return exists $self->data->[$key];
203             }
204             }
205              
206             sub SCALAR {
207 0     0   0 my ( $self ) = @_;
208 0         0 return scalar %{$self->data};
  0         0  
209             }
210              
211             sub CLEAR {
212 3     3   3921 my ( $self ) = @_;
213 3 100       27 if ($self->tied eq 'HASH') {
    50          
214 2         11 $self->save_file({});
215             } elsif ($self->tied eq 'ARRAY') {
216 1         5 $self->save_file([]);
217             }
218             }
219              
220 1     1   219 sub EXTEND {}
221 0     0   0 sub STORESIZE {}
222              
223             sub FIRSTKEY {
224 6     6   2608 my ( $self ) = @_;
225 6 50       27 if ($self->tied eq 'HASH') {
    0          
226 6         8 my ( $first ) = sort { $a cmp $b } keys %{$self->data};
  8         96  
  6         17  
227 6 50       108 return defined $first ? ($first) : ();
228             } elsif ($self->tied eq 'ARRAY') {
229 0 0       0 return scalar @{$self->data} ? (0) : ();
  0         0  
230             }
231             }
232              
233             sub NEXTKEY {
234 12     12   45 my ( $self, $last ) = @_;
235 12 50       39 if ($self->tied eq 'HASH') {
    0          
236 12         16 my @sorted_keys = sort { $a cmp $b } keys %{$self->data};
  24         299  
  12         23  
237 12         154 while (@sorted_keys) {
238 21         28 my $key = shift @sorted_keys;
239 21 100       62 if ($key eq $last) {
240 12 100       25 if (@sorted_keys) {
241 6         27 return (shift @sorted_keys);
242             } else {
243 6         30 return;
244             }
245             }
246             }
247             } elsif ($self->tied eq 'ARRAY') {
248 0         0 my $last_index = (scalar @{$self->data}) - 1;
  0         0  
249 0 0       0 if ($last < $last_index) {
250 0         0 return $last+1;
251             } else {
252 0         0 return;
253             }
254             }
255             }
256              
257 3     3   167 sub UNTIE {}
258 0     0     sub DESTROY {}
259              
260             1;
261              
262             __END__