File Coverage

blib/lib/JSON_File.pm
Criterion Covered Total %
statement 79 121 65.2
branch 19 44 43.1
condition n/a
subroutine 23 31 74.1
pod 0 6 0.0
total 121 202 59.9


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