File Coverage

blib/lib/Data/Printer/Profile/JSON.pm
Criterion Covered Total %
statement 52 52 100.0
branch 7 10 70.0
condition 1 3 33.3
subroutine 11 11 100.0
pod 0 1 0.0
total 71 77 92.2


line stmt bran cond sub pod time code
1             package Data::Printer::Profile::JSON;
2 1     1   9 use strict;
  1         2  
  1         40  
3 1     1   7 use warnings;
  1         2  
  1         1165  
4              
5             sub profile {
6             return {
7 1     1 0 27 show_tainted => 0,
8             show_unicode => 0,
9             show_lvalue => 0,
10             print_escapes => 0,
11             scalar_quotes => q("),
12             escape_chars => 'none',
13             string_max => 0,
14             unicode_charnames => 0,
15             array_max => 0,
16             index => 0,
17             hash_max => 0,
18             hash_separator => ': ',
19             align_hash => 0,
20             sort_keys => 0,
21             quote_keys => 1,
22             name => 'var',
23             return_value => 'dump',
24             output => 'stderr',
25             indent => 2,
26             show_readonly => 0,
27             show_tied => 0,
28             show_dualvar => 'off',
29             show_weak => 0,
30             show_refcount => 0,
31             show_memsize => 0,
32             separator => ',',
33             end_separator => 0,
34             caller_info => 0,
35             colored => 0,
36             class_method => undef,
37             # Data::Printer doesn't provide a way to directly
38             # decorate filters, so we do it ourselves:
39             filters => [
40             {
41             '-class' => \&_json_class_filter,
42             'SCALAR' => \&_json_scalar_filter,
43             'LVALUE' => \&_json_scalar_filter,
44             'CODE' => \&_json_code_filter,
45             'FORMAT' => \&_json_format_filter,
46             'GLOB' => \&_json_glob_filter,
47             'REF' => \&_json_ref_filter,,
48             'Regexp' => \&_json_regexp_filter,
49             'VSTRING' => \&_json_vstring_filter,
50             },
51             ],
52             };
53             }
54              
55             sub _json_class_filter {
56 1     1   3 my ($obj, $ddp) = @_;
57 1         6 Data::Printer::Common::_warn($ddp, 'json cannot express blessed objects. Showing internals only');
58 1         11 require Scalar::Util;
59 1         4 my $reftype = Scalar::Util::reftype($obj);
60 1 50       4 $reftype = 'Regexp' if $reftype eq 'REGEXP';
61 1         5 $ddp->indent;
62 1         4 my $string = $ddp->parse_as($reftype, $obj);
63 1         4 $ddp->outdent;
64 1         4 return $string;
65             }
66              
67             sub _json_ref_filter {
68 3     3   7 my ($ref, $ddp) = @_;
69 3         8 my $reftype = ref $$ref;
70 3 50 33     17 if ($reftype ne 'HASH' && $reftype ne 'ARRAY') {
71 3         12 Data::Printer::Common::_warn($ddp, 'json cannot express references to scalars. Cast to non-reference');
72             }
73 3         30 require Scalar::Util;
74 3         11 my $id = pack 'J', Scalar::Util::refaddr($$ref);
75 3 100       10 if ($ddp->seen($$ref)) {
76 2         7 Data::Printer::Common::_warn($ddp, 'json cannot express circular references. Cast to string');
77 2         24 return '"' . $ddp->parse($$ref) . '"';
78             }
79 1         4 return $ddp->parse($$ref);
80             }
81              
82             sub _json_glob_filter {
83 1     1   3 my (undef, $ddp) = @_;
84 1         5 Data::Printer::Common::_warn($ddp, 'json cannot express globs.');
85 1         6 return '';
86             }
87              
88             sub _json_format_filter {
89 1     1   6 my $res = Data::Printer::Filter::FORMAT::parse(@_);
90 1         6 return '"' . $res . '"';
91             }
92              
93             sub _json_regexp_filter {
94 1     1   4 my ($re, $ddp) = @_;
95 1         6 Data::Printer::Common::_warn($ddp, 'regular expression cast to string (flags removed)');
96 1         6 my $v = "$re";
97 1         3 my $mod = "";
98 1 50       9 if ($v =~ /^\(\?\^?([msixpadlun-]*):([\x00-\xFF]*)\)\z/) {
99 1         4 $mod = $1;
100 1         3 $v = $2;
101 1         4 $mod =~ s/-.*//;
102             }
103 1         2 $v =~ s{/}{\\/}g;
104 1         6 return '"' . "/$v/$mod" . '"';
105             }
106              
107             sub _json_vstring_filter {
108 1     1   4 my ($scalar, $ddp) = @_;
109 1         6 Data::Printer::Common::_warn($ddp, 'json cannot express vstrings. Cast to string');
110 1         6 my $ret = Data::Printer::Filter::VSTRING::parse(@_);
111 1         5 return '"' . $ret . '"';
112             }
113              
114             sub _json_scalar_filter {
115 6     6   14 my ($scalar, $ddp) = @_;
116 6 100       22 return $ddp->maybe_colorize('null', 'undef') if !defined $$scalar;
117 5         21 return Data::Printer::Filter::SCALAR::parse(@_);
118             }
119              
120             sub _json_code_filter {
121 1     1   3 my (undef, $ddp) = @_;
122 1         6 Data::Printer::Common::_warn($ddp, 'json cannot express subroutines. Cast to string');
123 1         9 my $res = Data::Printer::Filter::CODE::parse(@_);
124 1         6 return '"' . $res . '"';
125             }
126              
127             1;
128             __END__
129              
130             =head1 NAME
131              
132             Data::Printer::Profile::JSON - dump variables in JSON format
133              
134             =head1 SYNOPSIS
135              
136             While loading Data::Printer:
137              
138             use DDP profile => 'JSON';
139              
140             While asking for a print:
141              
142             p $var, profile => 'JSON';
143              
144             or in your C<.dataprinter> file:
145              
146             profile = JSON
147              
148             =head1 DESCRIPTION
149              
150             This profile outputs your variables in JSON format. It's not nearly as efficient
151             as a regular JSON module, but it may be useful, specially if you're changing
152             the format directly in your .dataprinter.
153              
154             =head1 CAVEATS
155              
156             JSON is a super simple format that allows scalar, hashes and arrays. It doesn't
157             support many types that could be present on Perl data structures, such as
158             functions, globs and circular references. When printing those types, whenever
159             possible, this module will stringify the result.
160              
161             Objects are also not shown, but their internal data structure is exposed.
162              
163             This module also attempts to render Regular expressions as plain JS regexes.
164             While not directly supported in JSON, it should be parseable.
165              
166             =head1 SEE ALSO
167              
168             L<Data::Printer>
169             L<JSON::MaybeXS>>