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   94614 use strict;
  1         3  
  1         41  
4 1     1   7 use warnings;
  1         4  
  1         41  
5 1     1   516 use Mojo::Util 'monkey_patch';
  1         146126  
  1         127  
6 1     1   461 use JSON::MaybeXS 'JSON';
  1         4097  
  1         47  
7 1     1   259 use Mojo::JSON ();
  1         13112  
  1         265  
8              
9             our $VERSION = '1.000';
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   33696 monkey_patch 'Mojo::JSON', 'encode_json', sub { $BINARY->encode($_[0]) };
34 68     68   41786 monkey_patch 'Mojo::JSON', 'decode_json', sub { $BINARY->decode($_[0]) };
35              
36 2     2   22 monkey_patch 'Mojo::JSON', 'to_json', sub { $TEXT->encode($_[0]) };
37 3     3   1085 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 or L, will attempt to guess if
144             a value to be encoded is numeric or string based on its last usage. Therefore,
145             using a variable containing C<13> in a string will cause it to be encoded as
146             C<"13"> even if the variable itself was not changed. L or
147             L version 3.0109 or greater will encode C<13> as C<13>
148             regardless of whether it has been used as a string.
149              
150             my ($num1, $num2) = (13, 14);
151             my $str = "$num1";
152             print encode_json([$num1, $num2, $str]);
153             # Mojo::JSON or Cpanel::JSON::XS >= 3.0109: [13,14,"13"]
154             # JSON::XS or JSON::PP: ["13",14,"13"]
155              
156             =head2 Duplicate Keys
157              
158             L, L, and L will silently accept duplicate keys
159             in the same JSON object when decoding a JSON string. L
160             version 3.0235 or greater will throw an exception if duplicate keys are
161             encountered.
162              
163             print dumper decode_json('{"foo":1, "bar":2, "foo":3}');
164             # Mojo::JSON, JSON::XS, or JSON::PP: { bar => 2, foo => 3 }
165             # Cpanel::JSON::XS >= 3.0235: "Duplicate keys not allowed" exception
166              
167             =head1 BUGS
168              
169             This is a monkey-patch of one of a few possible modules into another, and they
170             have incompatibilities, so there will probably be bugs. Report any issues on
171             the public bugtracker.
172              
173             =head1 AUTHOR
174              
175             Dan Book, C
176              
177             =head1 CREDITS
178              
179             Sebastian Riedel, author of L, for basic implementation.
180              
181             =head1 COPYRIGHT AND LICENSE
182              
183             Copyright 2014, Dan Book.
184              
185             This library is free software; you may redistribute it and/or modify it under
186             the terms of the Artistic License version 2.0.
187              
188             =head1 SEE ALSO
189              
190             L, L, L, L, L