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