File Coverage

blib/lib/JSON/Dumper/Compact.pm
Criterion Covered Total %
statement 30 32 93.7
branch n/a
condition n/a
subroutine 15 16 93.7
pod 2 2 100.0
total 47 50 94.0


line stmt bran cond sub pod time code
1             package JSON::Dumper::Compact;
2              
3 2     2   1434 use JSON::MaybeXS;
  2         4  
  2         110  
4 2     2   11 use Mu::Tiny;
  2         3  
  2         30  
5 2     2   1785 use Class::Method::Modifiers;
  2         2868  
  2         1088  
6              
7             our $VERSION = '0.006000';
8             $VERSION =~ tr/_//d;
9              
10             extends 'Data::Dumper::Compact';
11              
12             lazy json_obj => sub {
13             JSON->new
14             ->allow_nonref(1)
15             ->relaxed(1)
16             ->filter_json_single_key_object(__bless__ => sub {
17 1     1   41 bless($_[0][1], $_[0][0]);
18 19     19   160 });
19             };
20              
21 9     9   28 sub _json_decode { shift->json_obj->decode(@_) }
22              
23 70     70   360 sub _build_dumper { my $j = shift->json_obj; sub { $j->encode($_[0]) } }
  10     10   78  
  10         235  
24              
25 125     125   218 sub _format_el { shift->_format(@_).',' }
26              
27 39     39   113 sub _format_hashkey { $_[0]->json_obj->encode($_[1]).':' }
28              
29 147     147   570 sub _format_string { '"'.$_[1].'"' }
30              
31 20     20   69 sub _format_thing { $_[1] }
32              
33             around _expand_blessed => sub {
34             my ($orig, $self) = (shift, shift);
35             my ($blessed) = @_;
36             return $self->expand($blessed->TO_JSON) if $blessed->can('TO_JSON');
37             return $self->$orig(@_);
38             };
39              
40             sub _format_blessed {
41 2     2   6 my ($self, $payload) = @_;
42 2         4 my ($content, $class) = @$payload;
43 2         11 $self->_format([ hash => [
44             [ '__bless__' ],
45             { '__bless__' => [ array => [ [ string => $class ], $content ] ] },
46             ] ]);
47             }
48              
49             sub _format_ref {
50 6     6   7 my ($self, $payload) = @_;
51 6         12 my %subst = ('/' => '~1', '~' => '~0');
52 6         11 my @path = map { (my $x = $_->[1]) =~ s{[/~]}{$subst{$_}}eg; $x } @$payload;
  6         11  
  0         0  
  6         20  
53 6         28 return $self->format([ hash => [
54             [ '$ref' ],
55             { '$ref' => [ string => join('/', '#', @path) ] },
56             ] ]);
57             }
58              
59 0     0 1 0 sub encode { shift->dump(@_) }
60              
61             sub decode {
62 9     9 1 49 my ($self, $data, $opts) = @_;
63 9         34 $self->_optify($opts, _json_decode => $data);
64             }
65              
66             1;
67              
68             =head1 NAME
69              
70             JSON::Dumper::Compact - JSON processing with L aesthetics
71              
72             =head1 SYNOPSIS
73              
74             use JSON::Dumper::Compact 'jdc';
75            
76             my $json = jdc($data);
77              
78             =head1 DESCRIPTION
79              
80             JSON::Dumper::Compact is a subclass of L that turns
81             arrayrefs and hashrefs intead into JSON.
82              
83             Deep data structures are rendered highly compactly:
84              
85             [
86             "1556933590.65383", "Fri May 3 18:33:10 2019", 26794, "INFO", 3,
87             [ "SRV:8FB66F32" ], [ [
88             "/opt/voice-srvc-native/bin/async-srvc-att-gateway-poller", 33,
89             "NERV::Voice::SRV::Native::AsyncSRVATTGatewayPoller::main",
90             ] ],
91             "batch_nena_messages returned", "OK", 6, { "FILENAME": "lqxw020323" },
92             1556933584, "lqxw020323",
93             ]
94              
95             To ease debugging, blessed references without a C method are
96             rendered as an object with a single two-element arrayref value:
97              
98             { "__bless__": [
99             "The::Class",
100             { "the": "object" },
101             ] }
102              
103             =head1 METHODS
104              
105             In addition to the L methods, we provide:
106              
107             =head2 encode
108              
109             JSON::Dumper::Compact->encode($data, \%opts?);
110             $jdc->encode($data, \%opts?);
111              
112             Operates identically to L but named to be less
113             confusing to code expecting a JSON object.
114              
115             =head2 decode
116              
117             JSON::Dumper::Compact->decode($string, \%opts?);
118             $jdc->decode($string, \%opts);
119              
120             Runs the supplied string through an L C with options
121             set to be able to reliably reparse what we can currently format - notably
122             setting C to allow for trailing commas and using
123             C to re-inflate blessed objects.
124              
125             Note that using this method on untrusted data is a security risk. While
126             C/C should be usable for JSON formatting, in general,
127             C fully rehydrates for debugging purposes and as such can e.g.
128             cause DESTROY methods to be called unexpectedly, which can allow a
129             malicious user to do things to your perl5 VM. Rather than using
130             debugging specific code on untrusted data, use L or
131             L directly (if the C output doesn't parse correctly
132             via other libraries, please report that as a bug)..
133              
134             DO NOT USE THIS METHOD ON UNTRUSTED DATA IT WAS NOT DESIGNED TO BE SECURE.
135              
136             =head1 COPYRIGHT
137              
138             Copyright (c) 2019 the L and
139             L as listed in L.
140              
141             =head1 LICENSE
142              
143             This library is free software and may be distributed under the same terms
144             as perl itself. See L.
145              
146             =cut