Commit | Line | Data |
3be1e192 |
1 | package JSON::MaybeXS; |
2 | |
3 | use strict; |
4 | use warnings FATAL => 'all'; |
5 | use base qw(Exporter); |
6 | |
86147f11 |
7 | our $VERSION = '1.002006'; |
44459f01 |
8 | |
16205c4a |
9 | sub _choose_json_module { |
10 | return 'Cpanel::JSON::XS' if $INC{'Cpanel/JSON/XS.pm'}; |
11 | return 'JSON::XS' if $INC{'JSON/XS.pm'}; |
3be1e192 |
12 | |
16205c4a |
13 | my @err; |
3be1e192 |
14 | |
16205c4a |
15 | return 'Cpanel::JSON::XS' if eval { require Cpanel::JSON::XS; 1; }; |
3be1e192 |
16 | push @err, "Error loading Cpanel::JSON::XS: $@"; |
16205c4a |
17 | |
18 | return 'JSON::XS' if eval { require JSON::XS; 1; }; |
19 | push @err, "Error loading JSON::XS: $@"; |
20 | |
21 | return 'JSON::PP' if eval { require JSON::PP; 1 }; |
22 | push @err, "Error loading JSON::PP: $@"; |
23 | |
24 | die join( "\n", "Couldn't load a JSON module:", @err ); |
25 | |
26 | } |
27 | |
28 | BEGIN { |
29 | our $JSON_Class = _choose_json_module(); |
30 | $JSON_Class->import(qw(encode_json decode_json)); |
3be1e192 |
31 | } |
32 | |
33 | our @EXPORT = qw(encode_json decode_json JSON); |
1ca3b561 |
34 | our @EXPORT_OK = qw(is_bool); |
bf8dbbe1 |
35 | our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ] ); |
3be1e192 |
36 | |
37 | sub JSON () { our $JSON_Class } |
38 | |
939f9a29 |
39 | sub new { |
40 | shift; |
41 | my %args = @_ == 1 ? %{$_[0]} : @_; |
42 | my $new = (our $JSON_Class)->new; |
43 | $new->$_($args{$_}) for keys %args; |
44 | return $new; |
45 | } |
46 | |
8e911b7e |
47 | use Scalar::Util (); |
1ca3b561 |
48 | |
49 | sub is_bool { |
50 | die 'is_bool is not a method' if $_[1]; |
51 | |
8e911b7e |
52 | Scalar::Util::blessed($_[0]) |
53 | and ($_[0]->isa('JSON::XS::Boolean') |
54 | or $_[0]->isa('JSON::PP::Boolean')); |
1ca3b561 |
55 | } |
56 | |
3be1e192 |
57 | 1; |
44459f01 |
58 | |
59 | =head1 NAME |
60 | |
c95d7d54 |
61 | JSON::MaybeXS - Use L<Cpanel::JSON::XS> with a fallback to L<JSON::XS> and L<JSON::PP> |
44459f01 |
62 | |
63 | =head1 SYNOPSIS |
64 | |
65 | use JSON::MaybeXS; |
66 | |
67 | my $data_structure = decode_json($json_input); |
68 | |
69 | my $json_output = encode_json($data_structure); |
70 | |
71 | my $json = JSON->new; |
72 | |
939f9a29 |
73 | my $json_with_args = JSON::MaybeXS->new(utf8 => 1); # or { utf8 => 1 } |
74 | |
44459f01 |
75 | =head1 DESCRIPTION |
76 | |
16205c4a |
77 | This module first checks to see if either L<Cpanel::JSON::XS> or |
78 | L<JSON::XS> is already loaded, in which case it uses that module. Otherwise |
79 | it tries to load L<Cpanel::JSON::XS>, then L<JSON::XS>, then L<JSON::PP> |
80 | in order, and either uses the first module it finds or throws an error. |
44459f01 |
81 | |
82 | It then exports the C<encode_json> and C<decode_json> functions from the |
83 | loaded module, along with a C<JSON> constant that returns the class name |
84 | for calling C<new> on. |
85 | |
5c581075 |
86 | If you're writing fresh code rather than replacing L<JSON.pm|JSON> usage, you might |
939f9a29 |
87 | want to pass options as constructor args rather than calling mutators, so |
88 | we provide our own C<new> method that supports that. |
89 | |
44459f01 |
90 | =head1 EXPORTS |
91 | |
1ca3b561 |
92 | C<encode_json>, C<decode_json> and C<JSON> are exported by default; C<is_bool> |
93 | is exported on request. |
44459f01 |
94 | |
95 | To import only some symbols, specify them on the C<use> line: |
96 | |
1ca3b561 |
97 | use JSON::MaybeXS qw(encode_json decode_json is_bool); # functions only |
44459f01 |
98 | |
99 | use JSON::MaybeXS qw(JSON); # JSON constant only |
100 | |
bf8dbbe1 |
101 | To import all available symbols, use C<:all>: |
102 | |
103 | use JSON::MaybeXS ':all'; |
104 | |
44459f01 |
105 | =head2 encode_json |
106 | |
107 | This is the C<encode_json> function provided by the selected implementation |
0629a8af |
108 | module, and takes a perl data structure which is serialised to JSON text. |
44459f01 |
109 | |
110 | my $json_text = encode_json($data_structure); |
111 | |
112 | =head2 decode_json |
113 | |
114 | This is the C<decode_json> function provided by the selected implementation |
115 | module, and takes a string of JSON text to deserialise to a perl data structure. |
116 | |
117 | my $data_structure = decode_json($json_text); |
118 | |
119 | =head2 JSON |
120 | |
121 | The C<JSON> constant returns the selected implementation module's name for |
122 | use as a class name - so: |
123 | |
124 | my $json_obj = JSON->new; # returns a Cpanel::JSON::XS or JSON::PP object |
125 | |
126 | and that object can then be used normally: |
127 | |
128 | my $data_structure = $json_obj->decode($json_text); # etc. |
129 | |
1ca3b561 |
130 | =head2 is_bool |
131 | |
132 | $is_boolean = is_bool($scalar) |
133 | |
134 | Returns true if the passed scalar represents either C<true> or |
135 | C<false>, two constants that act like C<1> and C<0>, respectively |
136 | and are used to represent JSON C<true> and C<false> values in Perl. |
137 | |
138 | Since this is a bare sub in the various backend classes, it cannot be called as |
139 | a class method like the other interfaces; it must be called as a function, with |
140 | no invocant. It supports the representation used in all JSON backends. |
141 | |
939f9a29 |
142 | =head1 CONSTRUCTOR |
143 | |
144 | =head2 new |
145 | |
16205c4a |
146 | With L<JSON::PP>, L<JSON::XS> and L<Cpanel::JSON::XS> you are required to call |
3c38e105 |
147 | mutators to set options, such as: |
939f9a29 |
148 | |
149 | my $json = $class->new->utf8(1)->pretty(1); |
150 | |
151 | Since this is a trifle irritating and noticeably un-perlish, we also offer: |
152 | |
153 | my $json = JSON::MaybeXS->new(utf8 => 1, pretty => 1); |
154 | |
155 | which works equivalently to the above (and in the usual tradition will accept |
156 | a hashref instead of a hash, should you so desire). |
157 | |
32af371c |
158 | =head1 BOOLEANS |
159 | |
160 | To include JSON-aware booleans (C<true>, C<false>) in your data, just do: |
161 | |
162 | use JSON::MaybeXS; |
163 | my $true = JSON->true; |
164 | my $false = JSON->false; |
165 | |
44459f01 |
166 | =head1 AUTHOR |
167 | |
168 | mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk> |
169 | |
170 | =head1 CONTRIBUTORS |
171 | |
0c45c84c |
172 | =over 4 |
173 | |
174 | =item * Clinton Gormley <drtech@cpan.org> |
175 | |
176 | =item * Karen Etheridge <ether@cpan.org> |
177 | |
178 | =back |
44459f01 |
179 | |
180 | =head1 COPYRIGHT |
181 | |
182 | Copyright (c) 2013 the C<JSON::MaybeXS> L</AUTHOR> and L</CONTRIBUTORS> |
183 | as listed above. |
184 | |
185 | =head1 LICENSE |
186 | |
187 | This library is free software and may be distributed under the same terms |
188 | as perl itself. |
189 | |
190 | =cut |