File Coverage

blib/lib/Mojo/JSON/MaybeXS.pm
Criterion Covered Total %
statement 19 19 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 28 28 100.0


line stmt bran cond sub pod time code
1             package Mojo::JSON::MaybeXS;
2              
3 1     1   180138 use strict;
  1         10  
  1         26  
4 1     1   4 use warnings;
  1         2  
  1         22  
5 1     1   4 use Mojo::Util 'monkey_patch';
  1         1  
  1         106  
6 1     1   410 use JSON::MaybeXS 'JSON';
  1         4932  
  1         44  
7 1     1   423 use Mojo::JSON ();
  1         15034  
  1         312  
8              
9             our $VERSION = '1.001';
10              
11             my $BINARY = JSON::MaybeXS->new(utf8 => 1, canonical => 1, allow_nonref => 1,
12             allow_unknown => 1, allow_blessed => 1, convert_blessed => 1);
13             my $TEXT = JSON::MaybeXS->new(utf8 => 0, canonical => 1, allow_nonref => 1,
14             allow_unknown => 1, allow_blessed => 1, convert_blessed => 1);
15             my $TRUE = JSON->true;
16             my $FALSE = JSON->false;
17              
18             if (JSON eq 'Cpanel::JSON::XS') {
19             local $@;
20             if (eval { Cpanel::JSON::XS->VERSION('3.0112'); 1 }) {
21             $BINARY->stringify_infnan;
22             $TEXT->stringify_infnan;
23             }
24             if (eval { Cpanel::JSON::XS->VERSION('3.0206'); 1 }) {
25             $BINARY->escape_slash;
26             $TEXT->escape_slash;
27             }
28             } elsif (JSON eq 'JSON::PP') {
29             $BINARY->escape_slash;
30             $TEXT->escape_slash;
31             }
32              
33 61     61   23164 monkey_patch 'Mojo::JSON', 'encode_json', sub { $BINARY->encode($_[0]) };
34 68     68   35709 monkey_patch 'Mojo::JSON', 'decode_json', sub { $BINARY->decode($_[0]) };
35              
36 2     2   15 monkey_patch 'Mojo::JSON', 'to_json', sub { $TEXT->encode($_[0]) };
37 3     3   901 monkey_patch 'Mojo::JSON', 'from_json', sub { $TEXT->decode($_[0]) };
38              
39             monkey_patch 'Mojo::JSON', 'true', sub () { $TRUE };
40             monkey_patch 'Mojo::JSON', 'false', sub () { $FALSE };
41              
42             1;
43              
44             =head1 NAME
45              
46             Mojo::JSON::MaybeXS - use JSON::MaybeXS as the JSON encoder for Mojolicious
47              
48             =head1 SYNOPSIS
49              
50             use Mojo::JSON::MaybeXS;
51             use Mojo::JSON qw/encode_json decode_json true false/;
52            
53             # Preload for scripts using Mojo::JSON
54             $ perl -MMojo::JSON::MaybeXS -S morbo myapp.pl
55            
56             # Must be set in environment for hypnotoad
57             $ PERL5OPT=-MMojo::JSON::MaybeXS hypnotoad myapp.pl
58              
59             =head1 DESCRIPTION
60              
61             L is a monkey-patch module for using L as
62             the JSON encoder for a L application, or anything else using
63             L. It must be loaded before L so the new functions will
64             be properly exported.
65              
66             =head1 CAVEATS
67              
68             L may load different modules behind the scenes depending on what
69             is available, and these modules have slightly different behavior from
70             L and occasionally from each other. References to the behavior of
71             L below are actually describing the behavior shared among the
72             modules it loads.
73              
74             L is used with the options C, C,
75             C, C, and C. C
76             enables sorting of hash keys when encoding to JSON objects as L
77             does. C allows encoding and decoding of bare values outside of
78             hash/array references, since L does not prevent this, in accordance
79             with L. The other options prevent
80             the encoder from blowing up when encountering values that cannot be represented
81             in JSON to better match the behavior of L; in most cases, where
82             L would stringify a reference, L with these settings
83             will encode it to C. See below for more specifics.
84              
85             To better match the behavior of L, certain options may be enabled
86             depending on the backend that is used. If L version 3.0112 or
87             greater is loaded, it will be used with the option C. If
88             either L of at least version 3.0206 or L is loaded,
89             it will be used with the option C.
90              
91             As of this writing, the author has found the following incompatibilities:
92              
93             =head2 Object Conversion
94              
95             Both L and L will attempt to call the TO_JSON method
96             of a blessed reference to produce a JSON-friendly structure. If that method
97             does not exist, L or L version 3.0207 or greater
98             will stringify the object, while L or L will always encode
99             it to C.
100              
101             print encode_json([DateTime->now]);
102             # Mojo::JSON or Cpanel::JSON::XS >= 3.0207: ["2014-11-30T04:31:13"]
103             # JSON::XS or JSON::PP: [null]
104              
105             =head2 Unblessed References
106              
107             L does not allow unblessed references other than to hashes,
108             arrays, or the scalar values C<0> and C<1>, and will encode them to C.
109             L will treat all scalar references the same as references to C<0>
110             or C<1> and will encode them to C or C depending on their boolean
111             value. Other references (code, filehandle, etc) will be stringified.
112              
113             print encode_json([\'asdf', sub { 1 }]);
114             # Mojo::JSON: [true,"CODE(0x11d1650)"]
115             # JSON::MaybeXS: [null,null]
116              
117             =head2 Escapes
118              
119             L currently escapes the slash character C for security reasons,
120             as well as the unicode characters C and C. L
121             version 3.0206 or greater and L will have the option set to escape
122             the slash character, and L does not escape these characters. This
123             does not affect decoding of the resulting JSON.
124              
125             print encode_json(["/\x{2028}/\x{2029}"]);
126             # Mojo::JSON: ["\/\u2028\/\u2029"]
127             # Cpanel::JSON::XS >= 3.0206 or JSON::PP: ["\/ \/ "]
128             # JSON::XS: ["/ / "]
129             # Both decode to arrayref containing: "/\x{2028}/\x{2029}"
130              
131             =head2 inf and nan
132              
133             L encodes C and C to strings. L version
134             3.0112 or greater will also stringify C and C. However, L
135             or L will encode them as numbers (barewords) producing invalid JSON.
136              
137             print encode_json([9**9**9, -sin 9**9**9]);
138             # Mojo::JSON or Cpanel::JSON::XS >= 3.0112: ["inf","nan"] (on Linux)
139             # JSON::XS or JSON::PP: [inf,nan]
140              
141             =head2 Upgraded Numbers
142              
143             L, if using L, will attempt to guess if a value to be
144             encoded is numeric or string based on whether Perl has ever populated a string
145             value for it internally. Therefore, using a variable containing C<13> in a
146             string context will cause it to be encoded as C<"13"> even if the variable
147             itself was not changed. L, L version 2.92 or greater, or
148             L version 3.0109 or greater will encode C<13> as C<13>
149             regardless of whether it has been used as a string.
150              
151             my ($num1, $num2) = (13, 14);
152             my $str = "$num1";
153             print encode_json([$num1, $num2, $str]);
154             # Mojo::JSON, JSON::PP >= 2.92, Cpanel::JSON::XS >= 3.0109: [13,14,"13"]
155             # JSON::XS: ["13",14,"13"]
156              
157             =head2 Duplicate Keys
158              
159             L, L, and L will silently accept duplicate keys
160             in the same JSON object when decoding a JSON string. L
161             version 3.0235 or greater will throw an exception if duplicate keys are
162             encountered.
163              
164             print dumper decode_json('{"foo":1, "bar":2, "foo":3}');
165             # Mojo::JSON, JSON::XS, or JSON::PP: { bar => 2, foo => 3 }
166             # Cpanel::JSON::XS >= 3.0235: "Duplicate keys not allowed" exception
167              
168             =head1 BUGS
169              
170             This is a monkey-patch of one of a few possible modules into another, and they
171             have incompatibilities, so there will probably be bugs. Report any issues on
172             the public bugtracker.
173              
174             =head1 AUTHOR
175              
176             Dan Book, C
177              
178             =head1 CREDITS
179              
180             Sebastian Riedel, author of L, for basic implementation.
181              
182             =head1 COPYRIGHT AND LICENSE
183              
184             Copyright 2014, Dan Book.
185              
186             This library is free software; you may redistribute it and/or modify it under
187             the terms of the Artistic License version 2.0.
188              
189             =head1 SEE ALSO
190              
191             L, L, L, L, L