Skip to content

kfly8/p5-JSON-TypeEncoder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Coverage Status MetaCPAN Release

NAME

JSON::TypeEncoder - serialize JSON using type information

SYNOPSIS

use JSON::TypeEncoder;
use Types::Standard -types;

my $type = Dict[a => Str, b => Int, c => Bool];

my $jsont = JSON::TypeEncoder->new;
my $encode = $jsont->encoder($type);

$encode->({ a => 'foo', b => 30, c => !!1 });
# => {"a":"foo","b":30,"c":true}

DESCRIPTION

JSON::TypeEncoder serialize Perl data structures to JSON using type information. This module goal is to be correct and fast.

FEATURES

Correct

This module encodes according to the specified type information. For example, it encodes as following:

use JSON::TypeEncoder;
use Types::Standard -types;

my $jsont = JSON::TypeEncoder->new;

my $s = $jsont->encoder(Dict[a => Str]);
$s->({a => 123}); # => {"a":"123"}

my $i = $jsont->encoder(Dict[a => Int]);
$i->({a => 123}); # => {"a":123}

my $b = $jsont->encoder(Dict[a => Bool]);
$b->({a => !!0}); # => {"a":false}

This will prevent unintended encoding.

Fast

Encoding performance is improved by string eval using type information. You can get speed comparable to JSON::XS. The results of a simple benchmark is as following.

First comes a comparison using a very short single-line JSON string (also available at http://dist.schmorp.de/misc/json/short.json).

{"method": "handleMessage", "params": ["user1", "we were just talking"], "id": null, "array":[1,11,234,-5,1e5,1e7, 1,  0]}

It shows the number of encodes per second. Higher is better:

#                       Rate JSON::PP JSON::XS w/ Types JSON::TypeEncoder JSON::XS
# JSON::PP           39739/s       --              -83%              -90%     -95%
# JSON::XS w/ Types 234056/s     489%                --              -42%     -72%
# JSON::TypeEncoder 405736/s     921%               73%                --     -51%
# JSON::XS          825118/s    1976%              253%              103%       --

Using a longer test string (roughly 18KB, generated from Yahoo! Locals search API (http://dist.schmorp.de/misc/json/long.json).

#                      Rate          JSON::PP          JSON::XS JSON::TypeEncoder
# JSON::PP            984/s                --              -96%              -97%
# JSON::XS          26946/s             2639%                --              -13%
# JSON::TypeEncoder 30919/s             3043%               15%                --

Pure Perl

This module is written by pure Perl. So you can easily install it.

NOT FEATURES

This module NOT supports decode JSON to Perl data structures. You should use other modules like JSON::XS to decode.

TYPE SPECIFICATION

Types::Standard is used for type specification. The basic types are as follows, you can specify the type of JSON by this combination.

Basic Types

  • Str

    Subtype of Str encodes always to string.

    my $encode = $jsont->encoder(Str);
    $encode->(123) # => "123"
  • Num

    Subtype of Num encodes always to number.

    my $encode = $jsont->encoder(Num);
    $encode->(123) # => 123
  • Bool

    Subtype of Bool encodes always to boolean.

    my $encode = $jsont->encoder(Bool);
    $encode->(123) # => true
  • Dict[...]

    Subtype of Dict[...] encodes always to map.

    my $encode = $jsont->encoder(Dict[a => Int]);
    $encode->({ a => 123 });   # => {"a":123}
    $encode->({ a => '123' }); # => {"a":123}
  • Tuple[...]

    Subtype of Tuple[A, B] encodes always to list of type A and B.

    my $encode = $jsont->encoder(Tuple[Int, Str]);
    $encode->([123, 456]); # => [123,"456"]
  • ArrayRef[`a]

    Subtype of ArrayRef[A] encodes always to list of all elements type A.

    my $encode = $jsont->encoder(ArrayRef[Bool]);
    $encode->([1,0,undef,!!0,\0]); # => [true,false,false,false,true]
  • Maybe

    Maybe encodes to undef if value is undef.

    my $encode = $jsont->encoder(Maybe[Str]);
    $encode->('hello'); # => "hello"
    $encode->(undef); # => null
  • Optional[`a]

    Dict[name => Str, id => Optional[Int]] allows { name => "Bob" } but not { name => "Bob", id => "BOB" }.

    my $encode = $jsont->encoder(Dict[a => Optional[Str]]);
    $encode->({a => 'foo'}); # => {"a":"foo"}
    $encode->({}); # => {}

More Example

use Types::Standard -types;
use JSON::TypeEncoder;

my $type = ArrayRef[
    Dict[
        name => Str,
        fg => Bool,
        foo => Optional[Str],
        bar => Maybe[Num]
    ]
];

my $encode = JSON::TypeEncoder->new->encoder($type);
$encode->(
    [
        { name => 'a', fg => !!1, foo => '1', bar => '10' },
        { name => 'b', fg => !!0,             bar => '11' },
        { name => 'c', fg => !!1, foo => '2', bar => undef },
        { name => 'd', fg => !!0,             bar => undef },
    ]
);

# =>
# [
#   {"bar":10,"fg":true,"foo":"1","name":"a"},
#   {"bar":11,"fg":false,"name":"b"},
#   {"bar":null,"fg":true,"foo":"2","name":"c"},
#   {"bar":null,"fg":false,"name":"d"}
# ]

SEE ALSO

JSON::XS

JSON::Types

Types::Standard

LICENSE

Copyright (C) kfly8.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

AUTHOR

kfly8 kfly@cpan.org

CONTRIBUTORS

  • karupanerura

About

serialize JSON using type information

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages