=encoding UTF-8

=head1 NAME

JSON::Create - turn a Perl variable into JSON

=head1 SYNOPSIS

    
    use JSON::Create 'create_json';
    my %hash = (a => 'b', c => 'd');
    print create_json (\%hash);
    


produces

    {"c":"d","a":"b"}

=head1 DESCRIPTION

This module produces JSON out of Perl. It offers a simple default
function L</create_json> which converts Perl into JSON using common
defaults, and a customizable object created with L</new> where the
user can specify a variety of behaviours. For example, Unicode
escaping into ASCII via L</unicode_escape_all>, floating point number
formatting via L</set_fformat>, escaping of slashes (/) with
L</escape_slash>, JSON serialization of objects with L</obj>, or
boolean handling with L</bool>.

=head1 EXAMPLES

The example programs in this documentation are all found in the
directory F<examples/> in the distribution. All the outputs below are
taken from the actual outputs of the example programs.

=head1 FUNCTIONS

=head2 create_json

    my $json = create_json (\%hash);

Convert a Perl hash reference or array reference into JSON. The return
value is the output JSON.

Details of the conversion of each type are given in
L</CONVERSIONS>.

=head1 CONVERSIONS

This section details what conversions are applied to the various
inputs to produce outputs.

=head2 Hashes

Associative arrays are converted to JSON objects. The keys are written
into JSON as strings, with any control characters escaped. The order
of the keys is as they are supplied by Perl.

    
    use JSON::Create 'create_json';
    my %example = (
        down => {
            and => {
                down => {
                    and => {
                        down => {
                            and => {
                                down => 'we go'
                            }
                        }
                    }
                }
            }
        },
    );
    print create_json (\%example);


outputs

    {"down":{"and":{"down":{"and":{"down":{"and":{"down":"we go"}}}}}}}

=head2 Arrays

Arrays are converted to JSON arrays. The order of the array is
identical to the Perl one.

    
    use utf8;
    use JSON::Create 'create_json';
    my @array = (1, 2, 2.5, 'Acme', 
             {
                 cats => [qw/mocha dusty milky/], 
                 dogs => [qw/Tico Rocky Pinky/],
             });
    print create_json (\@array);


outputs

    [1,2,2.5,"Acme",{"cats":["mocha","dusty","milky"],"dogs":["Tico","Rocky","Pinky"]}]

=head2 Scalars

Perl scalars are converted to strings, JSON integers or JSON floats.

=head3 Strings

As far as possible, strings are written as-is to the JSON. However,
JSON requires that strings be in Unicode, and that some whitespace and
control characters are escaped. (See L</RFC 7159>.)

Bytes of value less than 0x20 in a Perl string are converted into the
appropriate JSON escapes, either the whitespace escapes \b (backspace)
\r, \t, \n, and \f, or the form \u0001 for other control
characters. The backslash is written as C<\\> and double quotes are
written as C<\">.

    
    use JSON::Create 'create_json';
    # An example string containing various things.
    my $weirdstring = {weird => "\t\r\n\x00 " . '"' . '\\' . '/' };
    print create_json ($weirdstring);
    


outputs

    {"weird":"\t\r\n\u0000 \"\\/"}



The forward slash, /, known as "solidus" in the JSON specification, is
not escaped. This behaviour can be altered with the method L</escape_slash> (see below).

Unicode values U+2028 and U+2029 are escaped.  This behaviour can be altered with the method L</no_javascript_safe> (see below).  Other Unicode values are not escaped.
This behaviour can be altered with the method L</unicode_escape_all> (see below).

=head3 Integers

Integers are printed in the obvious way. Note that what you input to
Perl as an integer, Perl may interpret to be a floating point number,
if it has a very large absolute value, in which case this module will
print it out like a floating point number.

=head3 Floating point numbers

Finite floating point numbers are printed using printf formatting via
C<"%g">, like

    printf ("%g", $number);

This behaviour can be altered with the method L</set_fformat> (see below)

NaN (not a number) values are converted to C<"nan"> (the letters
C<nan> surrounded by double quotes). Positive and negative infinity
are converted to C<"inf"> and C<"-inf"> respectively. JSON does not
allow NaN or infinity as bare values. From page 6 of L</RFC 7159>:

=over

Numeric values that cannot be represented in the grammar below (such
as Infinity and NaN) are not permitted.

=back

=head3 The undefined value

Undefined values are mapped to the JSON literal "null".

=head3 Booleans

Booleans (C<true> and C<false>) from input via JSON::Parse version
0.37 or later will be turned into C<true> and C<false>. Perl objects
can be converted to booleans using the method L</bool> (see below).

=head3 Unicode

If any part of the input object is marked as "utf8" (multibyte
characters), every non-ASCII string in the input object needs to be
marked as such, otherwise the module prints a warning and returns an
undefined value. 

=head4 Unicode escapes

All Unicode characters except the below-mentioned pair are put into
the output JSON as-is. To convert non-ASCII characters into Unicode
escapes of the form C<\u3000>, use the method L</unicode_escape_all>
(see below).

=head4 U+2028 and U+2029 (JavaScript clashes)

    my $out = create_json (["\x{2028}"]);
    # $out = '["\u2028"]'

L</create_json> escapes Unicode code points U+2028 and U+2029 as
C<\u2028> and C<\u2029> for JavaScript compatibility. This behaviour can be altered with the method L</no_javascript_safe> (see below).

This escaping is necessary because of a clash between the JSON
standard and the JavaScript (ECMAScript) standard. The characters
U+2028 ("LINE SEPARATOR" in the Unicode standard) and U+2029
("PARAGRAPH SEPARATOR" in the Unicode standard) are valid within JSON,
as defined by L</RFC 7159>, but invalid within JavaScript strings, as
defined by the ECMA standard (See ECMA Standard ECMA-262, "ECMAScript
Language Specification", 3rd Edition, section 7.3 "Line Terminators").

=head2 Other types

=head3 Regexes

If the scalar contains a regex then JSON::Create lets Perl convert the
regex to a string then adds that. The exact output depends on the Perl
version.

=head3 Objects

Perl objects (blessed references) are dereferenced and then handed as
if non-object types. This behaviour can be altered with the method L</obj> (see below).

=head3 Code references

A code reference in the input prints a warning and causes the entire
return value to be the undefined value. This behaviour can be altered with the method L</code_ref_handler> (see below).

=head3 Other references

Any other type of reference (glob etc.) causes a warning to be printed
and the return value to be the undefined value.

=head1 METHODS

To alter the format of the output from the defaults of
L</create_json>, create an object with L</new> and then set
preferences on that object before producing output with L</run>.

=head2 new

    my $jc = JSON::Create->new ();

Create a new "JSON::Create" object. You need to use L</run> to
generate JSON with this.

=head2 run

    my $json = $jc->run ($input);

This does exactly the same thing as L</create_json>, unless you have
altered the output format. The return value is the output JSON.

=head2 Methods for formatting the output

These methods work on the object created with L</new> to format the
output JSON in a different way from the default.

=head3 bool

    $jc->bool ('boolean');
    $jc->bool (qw/boolean JSON::Tiny::_Bool/);

The argument is a list of object names. The JSON::Create object,
C<$jc> in the example, will convert objects of these types into the
JSON literals C<true> or C<false> depending on whether Perl thinks
they're true or false. For example,

    
    use JSON::Create;
    use boolean;
    my $thing = {'Yes' => true, 'No' => false};
    my $jc = JSON::Create->new ();
    print $jc->run ($thing), "\n";
    $jc->bool ('boolean');
    print $jc->run ($thing), "\n";
    


outputs

    {"Yes":1,"No":0}
    {"Yes":true,"No":false}


=head4 Interoperability

The boolean values of the following Perl modules can interoperate with
JSON::Create. 

=over

=item L<boolean>

    $jc->bool ('boolean');

=item L<JSON::Tiny>

    $jc->bool ('JSON::Tiny::_Bool');

Round trip compatibility is also confirmed for JSON::Tiny version 0.54.

=item L<JSON::PP>

    $jc->bool ('JSON::PP::Boolean');

Round trip compatibility is also confirmed for JSON::PP version 2.27300.

=item L<Types::Serialiser>

    $jc->bool ('JSON::PP::Boolean');

B<Please note> the above is not a typo, L<JSON::PP::Boolean> is the
correct object type for Types::Serialiser. To confirm this, try

    print ref $Types::Serialiser::false;

=item L<Mojo::JSON>

    $jc->bool ('JSON::PP::Boolean', 'Mojo::JSON::_Bool');

Round trip compatibility is also confirmed for Mojo::JSON version 6.25.

The current version of Mojo::JSON (Mojolicious version 6.25) actually
depends on L<JSON::PP> and uses the type C<JSON::PP::Boolean> for its
true and false values. Older versions used their own type,
C<Mojo::JSON::_Bool>.

JSON::Create's tests for Mojo::JSON compatibility are currently
commented out by default, because different versions of Mojolicious
differ a lot in not only function names but also variable names, as
seen above. If you want to run these tests, please edit the file
F<t/bool.t> in the distribution.

=back

You can also switch on multiple modules using a list:

    $jc->bool (qw/boolean JSON::Tiny::_Bool JSON::PP::Boolean/);

The compatibility of the above modules can be confirmed by running the
test script F<t/bool.t> in the distribution. However, JSON::Create
does not install these modules, so unless you have installed them
yourself, the tests will just be skipped.

More modules will be added to this list as time permits.

=head3 code_ref_handler

    $jc->code_ref_handler (sub {return 'null'});

If you want to handle code references within the input, you can pass a
code reference handler to the JSON::Create object. This is called when
a code reference is found in the input. For example, if you want to
put the JSON literal C<null> in the output when you find a code
reference, the above example will do it. 

The code reference handler takes one value, which is the code
reference it is supposed to handle, and should return one value, a
valid JSON string.  If you want to have your return value validated,
use the L</validate> option (see below).

The method that code references are handled with the handler is very
similar to the way that objects are handled. See also L</obj>.

=head3 escape_slash

    $jc->escape_slash (1);

Call this with a true value to make the slash (known as the "solidus"
in the JSON specification) be escaped with a backslash. Call this with
any false value to make the slash not be escaped (the default
behaviour).

    
    use JSON::Create;
    my $jc = JSON::Create->new ();
    my $in = {'/dog/' => '/run/'};
    print $jc->run ($in), "\n";
    $jc->escape_slash (1);
    print $jc->run ($in), "\n";
    $jc->escape_slash (0);
    print $jc->run ($in), "\n";


outputs

    {"/dog/":"/run/"}
    {"\/dog\/":"\/run\/"}
    {"/dog/":"/run/"}


=head3 no_javascript_safe

    $jc->no_javascript_safe (1);

If called with a true value, this switches off JavaScript protection
in the output JSON. If called with a false value, the JavaScript
protection is switched on again.

    
    binmode STDOUT, ":utf8";
    use JSON::Create;
    my $in = ["\x{2028}"];
    my $jc = JSON::Create->new ();
    print $jc->run ($in), "\n";
    $jc->no_javascript_safe (1);
    print $jc->run ($in), "\n";
    


produces

    ["\u2028"]
    [" "]


See also L</U+2028 and U+2029 (JavaScript clashes)>.

=head3 obj

    $jc->obj ('Zilog::Z80' => sub { my ($obj) = @_; print "\"Z80\""; });

Register JSON generators for Perl objects. When JSON::Create finds an
object with a registered type, it will call the method you have
supplied.

The argument to C<obj> is a hash. The keys are object names, and the
corresponding values are code references to the JSON serializer for
that object:

    $jc->obj (
        'My::Object' => \& object_to_json,
    );

The function is called with the object reference as its only
argument, as if called like this:

    my $user_json = $my_object->object_to_json ();

The return value of the function, C<object_to_json> in the above
example, must be a single value, a string containing the object's JSON
encoding.

    
    use JSON::Create;
    my $jc = JSON::Create->new ();
    package Zilog::Z80;
    sub new { return bless { memory => '64 kbytes' }; }
    sub to_json {
        my ($self) = @_;
        return '"I can address as many as '.$self->{memory}.' of memory"';
    }
    1;
    package main;
    my $zilog = Zilog::Z80->new ();
    my %stuff = (zilog => $zilog);
    print $jc->run (\%stuff), "\n";
    # Set up our object's method for printing JSON.
    $jc->obj (
        'Zilog::Z80' => \& Zilog::Z80::to_json,
    );
    print $jc->run (\%stuff), "\n";


produces

    {"zilog":{"memory":"64 kbytes"}}
    {"zilog":"I can address as many as 64 kbytes of memory"}


The output is passed through to the output string unaltered. To have
your JSON output checked for validity, use the L</validate> option.

Remember that if you need to pass or return more than a single
argument, you can use a closure:

    
    use JSON::Create;
    package My::Cool::Object;
    sub new { return bless {}; }
    sub serialize { return ('true', 'false'); };
    1;
    package main;
    my $object = My::Cool::Object->new ();
    my $jc = JSON::Create->new ();
    my ($arg1, $arg2);
    $jc->obj (
        'My::Cool::Object' => sub {
            my ($obj) = @_;
            my ($value1, $value2) = My::Cool::Object::serialize ($obj, $arg1, $arg2);
            return $value2;
        },
    );
    print $jc->run ({cool => $object});


produces

    {"cool":false}

=head3 set_fformat

    $jc->set_fformat ('%e');

This sets the printf-style format string used to print floating point
numbers. This is validated and a warning printed if the format cannot
be used. The format is also restricted to a maximum length to prevent
buffer overflows within the module.

    
    use JSON::Create;
    my $jc = JSON::Create->new ();
    my @array = (1000000000.0,3.141592653589793238462643383279502884197169399375105820974944592307816406,0.000000001);
    print $jc->run (\@array), "\n";
    $jc->set_fformat ('%.3f');
    print $jc->run (\@array), "\n";
    $jc->set_fformat ('%E');
    print $jc->run (\@array), "\n";
    $jc->set_fformat ();
    print $jc->run (\@array), "\n";


outputs

    [1e+09,3.14159,1e-09]
    [1000000000.000,3.142,0.000]
    [1.000000E+09,3.141593E+00,1.000000E-09]
    [1e+09,3.14159,1e-09]


=head3 unicode_escape_all

    $jc->unicode_escape_all (1);

Call this with a true value to make all Unicode characters be escaped
into the C<\u3000> format. A false value switches that off again.

    
    use JSON::Create;
    use utf8;
    binmode STDOUT, ":utf8";
    my $jc = JSON::Create->new ();
    my $in = '赤ブöＡↂϪ';
    print $jc->run ($in), "\n";
    $jc->unicode_escape_all (1);
    print $jc->run ($in), "\n";
    $jc->unicode_upper (1);
    print $jc->run ($in), "\n";
    $jc->unicode_escape_all (0);
    print $jc->run ($in), "\n";


outputs

    "赤ブöＡↂϪ"
    "\u8d64\u30d6\u00f6\uff21\u2182\u03ea"
    "\u8D64\u30D6\u00F6\uFF21\u2182\u03EA"
    "赤ブöＡↂϪ"


=head3 unicode_upper

    $jc->unicode_upper (1);

Call this with a true value to make Unicode escapes use upper case
hexadecimal. See the example under L</unicode_escape_all>.

=head3 validate

    $jc->validate (1);

If this is called with a true value, JSON::Create validates the
user-generated JSON given by the callbacks registered with L</obj> and
L</code_ref_handler>. The validation is done via the routine
C<assert_valid_json> of L<JSON::Parse>, so that module must be
installed, otherwise the call to C<validate> will fail.

If JSON::Parse is installed, and the JSON fails to validate, this will
produce a warning containing the string and the error produced by
C<assert_valid_json>, and the return value will be undefined.

=head1 EXPORTS

The module exports nothing except by request. One function,
L</create_json>, is exported on request.

=head1 INSTALLATION

The module uses C internally, so you need a C compiler to install
it. There is also an undocumented "pure Perl" module JSON::Create::PP
in the distribution, which could be used in a pinch. (This is
basically a reference module though.)

=head1 SEE ALSO

=over

=item RFC 7159

JSON is specified in L<RFC 7159 "The application/json Media Type for
JavaScript Object Notation
(JSON)"|http://www.ietf.org/rfc/rfc7159.txt>.

=item json.org

L<http://json.org> is the website for JSON, authored by Douglas
Crockford.

=item JSON::Parse

This module is a companion module to the same author's
L<JSON::Parse>. Please see that module's documentation for links to
the JSON standard itself, a summary of the ever-growing list of JSON
modules on CPAN (under "SEE ALSO") and the reasons why I decided to
write these two modules (under "HISTORY").

=back

=head1 BUGS

There is currently no facility to add whitespace to the output JSON.

There is currently no way to delete object handlers from a
JSON::Create object.

There are a few remaining undecided issues around the default object
serialization.

=head1 PERFORMANCE

This module is fairly new on the scene, so speed is not a key issue
until the module is demonstrably producing correct outputs.

However, due to user interest, there is a benchmarking script in
F<bench/bench.pl> which compares the performance of the module with
L<JSON::XS> and L<Cpanel::JSON::XS>. Outputs look like this:

    Versions used:
    
    CJX	Cpanel::JSON::XS	3.0115
    JX	JSON::XS	3.01
    JC	JSON::Create	0.09
    
    Comparing hash of ASCII strings...
    
          Rate  CJX   JX   JC
    CJX 40.6/s   --  -2% -33%
    JX  41.6/s   2%   -- -31%
    JC  60.7/s  49%  46%   --
    
    Comparing hash of integers...
    
          Rate   JX  CJX   JC
    JX  16.2/s   --  -1% -54%
    CJX 16.3/s   1%   -- -53%
    JC  35.1/s 116% 115%   --
    
    Comparing hash of Unicode strings...
    
          Rate  CJX   JX   JC
    CJX 47.9/s   --  -1% -45%
    JX  48.3/s   1%   -- -45%
    JC  87.1/s  82%  80%   --
    
    Comparing array of floats...
    
          Rate  CJX   JX   JC
    CJX 14.0/s   --  -1% -60%
    JX  14.1/s   1%   -- -59%
    JC  34.7/s 147% 146%   --


This only compares a few simple cases in which the output is
demonstrably correct. Also, at least on my computer, the numbers seem
to vary wildly from one test to another.

=head1 HISTORY

I started making this module so that, with this and L<JSON::Parse>, I
wouldn't have to use the existing JSON modules on CPAN. See the
HISTORY section of the documentation of L<JSON::Parse> for full
details.

The exact time I've spent making this module is recorded in the file
F<timesheet.txt> in the top directory of the distribution. At the time
of version 0.09_02, I've spent 1 day, 6 hours and 41 minutes working
on this.

The module is currently in use everywhere that I need to generate JSON
within Perl. However, I would suggest caution in switching to this
module from the more established JSON solutions on CPAN, since while
most parts are implemented, there are some corner-cases and untested
code.


=head1 AUTHOR

Ben Bullock, <bkb@cpan.org>

=head1 COPYRIGHT & LICENCE

This package and associated files are copyright (C) 
2015
Ben Bullock.

You can use, copy, modify and redistribute this package and associated
files under the Perl Artistic Licence or the GNU General Public
Licence.


=head1 TERMINOLOGY

This defines the terminology used in this document.

=over

=item Convenience function

In this document, a "convenience function" indicates a function which
solves some of the problems, some of the time, for some of the people,
but which may not be good enough for all envisaged uses. A convenience
function is an 80/20 solution, something which solves (about) 80% of
the problems with 20% of the effort. Something which does the obvious
things, but may not do all the things you might want, a time-saver for
the most basic usage cases.

=item BUGS

In this document, the section BUGS describes possible deficiencies,
problems, and workarounds with the module. It's not a guide to bug
reporting, or even a list of actual bugs. The name "BUGS" is the
traditional name for this sort of section in a Unix manual page.

=back



=cut

