File Coverage

blib/lib/JSON/ize.pm
Criterion Covered Total %
statement 56 62 90.3
branch 18 24 75.0
condition 4 6 66.6
subroutine 18 20 90.0
pod 9 12 75.0
total 105 124 84.6


line stmt bran cond sub pod time code
1             package JSON::ize;
2 2     2   113575 use base Exporter;
  2         10  
  2         105  
3 2     2   683 use JSON::MaybeXS;
  2         11980  
  2         104  
4 2     2   629 use YAML::Any qw/Dump Load LoadFile DumpFile/;
  2         1912  
  2         6  
5 2     2   5696 use Try::Tiny;
  2         3208  
  2         86  
6 2     2   23 use strict;
  2         4  
  2         29  
7 2     2   8 use warnings;
  2         2  
  2         1589  
8              
9             our $JOBJ = JSON::MaybeXS->new();
10             our $YOBJ;
11             our $_last_out = "";
12              
13             our @EXPORT = qw/jsonize jsonise J yamlize yamlise Y parsej pretty_json ugly_json/;
14             our $VERSION = "0.201";
15              
16 15     15 0 180 sub jobj { $JOBJ }
17              
18             sub jsonize (;$) {
19 24     24 1 1198 my $inp = shift;
20 24 100       58 if (!defined $inp) {
21 4         18 return $_last_out;
22             }
23 20 100       39 if (ref $inp) { # encode perl object
24 5         14 my ($a,$b,$c,$subr,@rest) = caller(1);
25 5 100 66     107 return $_last_out = ($subr && $subr =~ /Y|yamli[sz]e$/) ? Dump($inp) : jobj()->encode($inp);
26             }
27             else { # scalar: decode if looks like json or yaml, or slurp if filename
28 15 100       27 if (looks_like_json($inp)) {
    50          
29 4         9 return $_last_out = jobj()->decode($inp);
30             }
31             elsif (looks_like_yaml($inp)) {
32 0         0 return $_last_out = Load($inp);
33             }
34             else { # try as file
35 11         31 local $/;
36 11         15 my ($j,$f);
37 11 100       185 die "'$inp' is not a existing filename, json string, or a reference" unless (-e $inp);
38 10 50       493 if ( eval "require PerlIO::gzip; 1" ) {
39 10 50       473 open $f, "<:gzip(autopop)", $inp or die "Problem with file '$inp' : $!";
40             }
41             else {
42 0 0       0 open $f, "$inp" or die "Problem with file '$inp' : $!";
43             }
44 10         148 $j = <$f>;
45             try {
46 10     10   929 $_last_out = jobj()->decode($j);
47             } catch {
48 6 50   6   102 /at character offset/ && do { # JSON error
49 6         9 my $jerr = $_;
50 6 100       11 if (looks_like_json($j)) { # probably really was JSON
51 2         39 die "JSON decode barfed.\nJSON err: $jerr"
52             }
53             try { # might be YAML
54 4         305 $_last_out = Load($j);
55             } catch {
56 2 100       194 if (looks_like_yaml($j)) {
57 1         21 die "YAML decode barfed.\nYAML err: $_";
58             }
59 1         22 die "Both JSON and YAML decodes barfed.\nJSON err: $jerr\nYAML err: $_";
60 4         21 };
61             };
62 10         81 };
63 6         465 return $_last_out;
64             }
65             }
66             }
67              
68 1     1 1 2 sub jsonise (;$) { jsonize($_[0]) }
69 4     4 1 11 sub J (;$) { jsonize($_[0]) }
70 3     3 1 8 sub yamlize (;$) { jsonize($_[0]) }
71 1     1 1 4 sub yamlise (;$) { jsonize($_[0]) }
72 1     1 1 3 sub Y (;$) { jsonize($_[0]) }
73              
74              
75             sub parsej () {
76 4     4 1 26 $_last_out = $JOBJ->incr_parse($_);
77             }
78              
79 0     0 1 0 sub pretty_json { jobj()->pretty; return; }
  0         0  
80 0     0 1 0 sub ugly_json { jobj()->pretty(0); return; }
  0         0  
81              
82             sub looks_like_json {
83 22     22 0 34 my $ck = $_[0];
84 22         94 return $ck =~ /^\s*[[{]/;
85             }
86              
87             sub looks_like_yaml {
88 19     19 0 881 my $ck = $_[0];
89 19         143 my @l = $ck =~ /^(?:---|\s+-\s\w+|\s*\w+\s?:\s+\S+)$/gm;
90 19   66     96 return @l && ($l[0] eq '---' || @l > 2 );
91             }
92              
93              
94             =head1 NAME
95              
96             JSON::ize - Use JSON easily in one-liners - now with YAMLific action
97              
98             =head1 SYNOPSIS
99              
100             $ perl -MJSON::ize -le '$j=jsonize("my.json"); print $j->{thingy};'
101              
102             $ perl -MJSON::ize -le '$j=jsonize("my.yaml"); print $j->{thingy};'
103              
104             # or yamlize, if you prefer
105              
106             $ perl -MJOSN::ize -le '$j=yamlize("my.yaml"); print $j->{thingy};'
107              
108             # plus yamls all the way down...
109              
110             # if you have PerlIO::gzip, this works
111              
112             $ perl -MJSON::ize -le '$j=jsonize("my.json.gz"); print $j->{thingy};'
113              
114             $ perl -MJSON::ize -le 'J("my.json"); print J->{thingy};' # short
115              
116             $ perl -MJSON::ize -le 'print J("my.json")->{thingy};' # shorter
117              
118             $ cat my.json | perl -MJSON::ize -lne 'parsej; END{ print J->{thingy}}' # another way
119              
120             $ perl -MJSON::ize -le '$j="{\"this\":\"also\",\"works\":[1,2,3]}"; print jsonize($j)->{"this"};' # also
121              
122             $ perl -MJSON::ize -e 'pretty_json(); $j=jsonize("ugly.json"); print jsonize($j);' # pretty!
123              
124             $ perl -MJSON::ize -e 'ugly_json; print J(J("indented.json"));' # strip whsp
125              
126             # JSON to YAML
127              
128             $ perl -MJSON::ize -e 'print yamlize jsonize "my.json"'
129              
130             $ perl -MJSON::ize -e 'print Y J "my.json"'
131              
132             # and back
133              
134             $ perl -MJSON::ize -e 'print jsonize yamlize "my.yaml"'
135              
136             $ perl -MJSON::ize -e 'print J Y "my.yaml"'
137              
138             =head1 DESCRIPTION
139              
140             JSON::ize exports a function, C, and some synonyms (see below), that will do what you mean with the argument.
141              
142             If argument is a filename, it will try to read the file and decode it from JSON or YAML.
143              
144             If argument is a string that looks like JSON or YAML, it will try to encode it:
145              
146             =over
147              
148             =item *
149              
150             If argument is a Perl hashref or arrayref, and you called C, it will try to encode it as JSON.
151              
152             =item *
153              
154             If argument is a Perl hashref or arrayref, and you called C, it will try to encode it as YAML.
155              
156             =back
157              
158             The underlying L object is
159              
160             $JSON::ize::JOBJ
161              
162             =head1 METHODS
163              
164             =over
165              
166             =item jsonize($j), jsonise($j), J($j)
167              
168             Try to DWYM. In particular, encode to JSON.
169             If called without argument, return the last value returned. Use this to retrieve
170             after L.
171              
172             =item yamlize($j), yamlise($j), Y($j)
173              
174             Try to DWYM. In particular, encode to YAML.
175             If called without argument, return the last value returned.
176              
177             =item parsej
178              
179             Parse a piped-in stream of json. Use jsonize() (without arg) to retrieve the object.
180             (Uses L.)
181              
182             =item pretty_json()
183              
184             Output pretty (indented) json.
185              
186             =item ugly_json()
187              
188             Output json with no extra whitespace.
189              
190             =back
191              
192             =head1 SEE ALSO
193              
194             L, L.
195              
196             =head1 AUTHOR
197              
198             Mark A. Jensen
199             CPAN: MAJENSEN
200             mark -dot- jensen -at- nih -dot- gov
201              
202             =head1 LICENSE
203              
204             Copyright (c) 2018, 2019 Mark A. Jensen.
205              
206             Licensed under the Apache License, Version 2.0 (the "License");
207             you may not use this file except in compliance with the License.
208             You may obtain a copy of the License at
209              
210             L
211              
212             Unless required by applicable law or agreed to in writing, software
213             distributed under the License is distributed on an "AS IS" BASIS,
214             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
215             See the License for the specific language governing permissions and
216             limitations under the License.
217              
218              
219             =cut
220              
221             1;