4 use warnings FATAL => 'all';
7 our $VERSION = '1.003_000'; # TRIAL RELEASE
8 $VERSION = eval $VERSION;
10 sub _choose_json_module {
11 return 'Cpanel::JSON::XS' if $INC{'Cpanel/JSON/XS.pm'};
12 return 'JSON::XS' if $INC{'JSON/XS.pm'};
16 return 'Cpanel::JSON::XS' if eval { require Cpanel::JSON::XS; 1; };
17 push @err, "Error loading Cpanel::JSON::XS: $@";
19 return 'JSON::XS' if eval { require JSON::XS; 1; };
20 push @err, "Error loading JSON::XS: $@";
22 return 'JSON::PP' if eval { require JSON::PP; 1 };
23 push @err, "Error loading JSON::PP: $@";
25 die join( "\n", "Couldn't load a JSON module:", @err );
30 our $JSON_Class = _choose_json_module();
31 $JSON_Class->import(qw(encode_json decode_json));
34 our @EXPORT = qw(encode_json decode_json JSON);
35 my @EXPORT_ALL = qw(is_bool);
36 our @EXPORT_OK = qw(is_bool to_json from_json);
37 our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_ALL ],
38 legacy => [ @EXPORT, @EXPORT_OK ],
41 sub JSON () { our $JSON_Class }
45 my %args = @_ == 1 ? %{$_[0]} : @_;
46 my $new = (our $JSON_Class)->new;
47 $new->$_($args{$_}) for keys %args;
54 die 'is_bool is not a method' if $_[1];
56 Scalar::Util::blessed($_[0])
57 and ($_[0]->isa('JSON::XS::Boolean')
58 or $_[0]->isa('JSON::PP::Boolean'));
61 # (mostly) CopyPasta from JSON.pm version 2.90
65 if ( ref($_[0]) =~ /^JSON/ or $_[0] =~ /^JSON/ ) {
66 Carp::croak "from_json should not be called as a method.";
68 my $json = JSON()->new;
70 if (@_ == 2 and ref $_[1] eq 'HASH') {
72 for my $method (keys %$opt) {
73 $json->$method( $opt->{$method} );
77 return $json->decode( $_[0] );
83 or (@_ > 2 and $_[0] =~ /^JSON/)
85 Carp::croak "to_json should not be called as a method.";
87 my $json = JSON()->new;
89 if (@_ == 2 and ref $_[1] eq 'HASH') {
91 for my $method (keys %$opt) {
92 $json->$method( $opt->{$method} );
103 JSON::MaybeXS - Use L<Cpanel::JSON::XS> with a fallback to L<JSON::XS> and L<JSON::PP>
109 my $data_structure = decode_json($json_input);
111 my $json_output = encode_json($data_structure);
113 my $json = JSON->new;
115 my $json_with_args = JSON::MaybeXS->new(utf8 => 1); # or { utf8 => 1 }
119 This module first checks to see if either L<Cpanel::JSON::XS> or
120 L<JSON::XS> is already loaded, in which case it uses that module. Otherwise
121 it tries to load L<Cpanel::JSON::XS>, then L<JSON::XS>, then L<JSON::PP>
122 in order, and either uses the first module it finds or throws an error.
124 It then exports the C<encode_json> and C<decode_json> functions from the
125 loaded module, along with a C<JSON> constant that returns the class name
126 for calling C<new> on.
128 If you're writing fresh code rather than replacing L<JSON.pm|JSON> usage, you might
129 want to pass options as constructor args rather than calling mutators, so
130 we provide our own C<new> method that supports that.
134 C<encode_json>, C<decode_json> and C<JSON> are exported by default; C<is_bool>
135 is exported on request.
137 To import only some symbols, specify them on the C<use> line:
139 use JSON::MaybeXS qw(encode_json decode_json is_bool); # functions only
141 use JSON::MaybeXS qw(JSON); # JSON constant only
143 To import all available sensible symbols (C<encode_json>, C<decode_json>, and
144 C<is_bool>), use C<:all>:
146 use JSON::MaybeXS ':all';
148 To import all symbols including those needed by legacy apps that use L<JSON::PP>:
150 use JSON::MaybeXS ':legacy';
152 This imports the C<to_json> and C<from_json> symbols as well as everything in
153 C<:all>. NOTE: This is to support legacy code that makes extensive
154 use of C<to_json> and C<from_json> which you are not yet in a position to
155 refactor. DO NOT use this import tag in new code, in order to avoid
156 the crawling horrors of getting UTF8 support subtly wrong. See the
157 documentation for L<JSON> for further details.
161 This is the C<encode_json> function provided by the selected implementation
162 module, and takes a perl data structure which is serialised to JSON text.
164 my $json_text = encode_json($data_structure);
168 This is the C<decode_json> function provided by the selected implementation
169 module, and takes a string of JSON text to deserialise to a perl data structure.
171 my $data_structure = decode_json($json_text);
173 =head2 to_json, from_json
175 See L<JSON> for details. These are included to support legacy code
180 The C<JSON> constant returns the selected implementation module's name for
181 use as a class name - so:
183 my $json_obj = JSON->new; # returns a Cpanel::JSON::XS or JSON::PP object
185 and that object can then be used normally:
187 my $data_structure = $json_obj->decode($json_text); # etc.
191 $is_boolean = is_bool($scalar)
193 Returns true if the passed scalar represents either C<true> or
194 C<false>, two constants that act like C<1> and C<0>, respectively
195 and are used to represent JSON C<true> and C<false> values in Perl.
197 Since this is a bare sub in the various backend classes, it cannot be called as
198 a class method like the other interfaces; it must be called as a function, with
199 no invocant. It supports the representation used in all JSON backends.
205 With L<JSON::PP>, L<JSON::XS> and L<Cpanel::JSON::XS> you are required to call
206 mutators to set options, such as:
208 my $json = $class->new->utf8(1)->pretty(1);
210 Since this is a trifle irritating and noticeably un-perlish, we also offer:
212 my $json = JSON::MaybeXS->new(utf8 => 1, pretty => 1);
214 which works equivalently to the above (and in the usual tradition will accept
215 a hashref instead of a hash, should you so desire).
219 To include JSON-aware booleans (C<true>, C<false>) in your data, just do:
222 my $true = JSON->true;
223 my $false = JSON->false;
227 mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
233 =item * Clinton Gormley <drtech@cpan.org>
235 =item * Karen Etheridge <ether@cpan.org>
237 =item * Kieren Diment <diment@gmail.com>
243 Copyright (c) 2013 the C<JSON::MaybeXS> L</AUTHOR> and L</CONTRIBUTORS>
248 This library is free software and may be distributed under the same terms