mirror https://github.com/sile/jsone

Takeru Ohta d0c1aaa408 Support basic pretty-print functionality 10 years ago
doc d0c1aaa408 Support basic pretty-print functionality 10 years ago
src d0c1aaa408 Support basic pretty-print functionality 10 years ago
test d0c1aaa408 Support basic pretty-print functionality 10 years ago
.gitignore 67a1b09ce3 Update rebar to 2.5.0 10 years ago
COPYING 0eb585b475 Refactoring 10 years ago
Makefile d0c1aaa408 Support basic pretty-print functionality 10 years ago
README.md d0c1aaa408 Support basic pretty-print functionality 10 years ago
rebar 67a1b09ce3 Update rebar to 2.5.0 10 years ago
rebar.config 3277c40d0d Support map 10 years ago

README.md

jsone (0.3.2)

An Erlang library for encoding, decoding JSON data.

Features

  • Provides simple encode/decode function only
  • RFC4627-compliant
  • Supports UTF-8 encoded binary
  • Pure Erlang
  • Highly Efficient
    • Maybe one of the fastest JSON library (except those which are implemented in NIF)
    • Decode function is written in continuation-passing style(CPS)

QuickStart

# clone
$ git clone git://github.com/sile/jsone.git
$ cd jsone

# If you want to use HiPE enabled version, please execute following command.
# $ git checkout hipe

# compile
$ make compile

# run tests
$ make eunit

# dialyze
$ make dialyze

# Erlang shell
$ make start
1> jsone:decode(<<"[1,2,3]">>).
[1,2,3]

Usage Example

%% Decode
> jsone:decode(<<"[1,2,3]">>).
[1,2,3]

> jsone:decode(<<"{\"1\":2}">>).
{[{<<"1">>,2}]}

> jsone:try_decode(<<"[1,2,3] \"next value\"">>). % try_decode/1 returns remaining (unconsumed binary)
{ok,[1,2,3],<<" \"next value\"">>}

% error: raises exception
> jsone:decode(<<"1.x">>).
** exception error: bad argument
     in function  jsone_decode:number_fraction_part_rest/6
        called as jsone_decode:number_fraction_part_rest(<<"x">>,1,1,0,[],<<>>)
     in call from jsone:decode/1 (src/jsone.erl, line 71)

% error: returns {error, Reason}
> jsone:try_decode(<<"1.x">>).
{error,{badarg,[{jsone_decode,number_fraction_part_rest,
                              [<<"x">>,1,1,0,[],<<>>],
                              [{line,228}]}]}}


%% Encode
> jsone:encode([1,2,3]).
<<"[1,2,3]">>

> jsone:encode({[{<<"key">>, <<"value">>}]}).
<<"{\"key\":\"value\"}">>

> jsone:encode({[{key, <<"value">>}]}). % atom key is allowed
<<"{\"key\":\"value\"}">>

% error: raises exception
> jsone:encode({[{123, <<"value">>}]}). % non binary|atom key is not allowed
** exception error: bad argument
     in function  jsone_encode:object_members/3
        called as jsone_encode:object_members([{123,<<"value">>}],[],<<"{">>)
     in call from jsone:encode/1 (src/jsone.erl, line 97)

% error: returns {error, Reason}
> jsone:try_encode({[{123, <<"value">>}]}).
{error,{badarg,[{jsone_encode,object_members,
                              [[{123,<<"value">>}],[],<<"{">>],
                              [{line,138}]}]}}

%% Pretty Print
> Data = [true, {[{<<"1">>, 2}, {<<"array">>, [[[[1]]], {[{<<"ab">>, <<"cd">>}]}, false]}]}, null],
> io:format("~s\n", jsone:encode(Data, [{indent, 1}, {space, 2}])).
[
  true,
  {
    "1": 2,
    "array": [
      [
        [
          [
            1
          ]
        ]
      ],
      {
        "ab": "cd"
      },
      false
    ]
  },
  null
]
ok

Data Mapping (Erlang <=> JSON)

Erlang                  JSON             Erlang
=================================================================================================

null                 -> null          -> null
true                 -> true          -> true
false                -> false         -> false
<<"abc">>            -> "abc"         -> <<"abc">>
abc                  -> "abc"         -> <<"abc">> % non-special atom is regarded as a binary
123                  -> 123           -> 123
123.4                -> 123.4         -> 123.4
[1,2,3]              -> [1,2,3]       -> [1,2,3]
{[]}                 -> {}            -> {[]}                       % object_format=tuple
{[{key, <<"val">>}]} -> {"key":"val"} -> {[{<<"key">>, <<"val">>}]} % object_format=tuple
[{}]                 -> {}            -> [{}]                       % object_format=proplist
[{<<"key">>, val}]   -> {"key":"val"} -> [{<<"key">>, <<"val">>}]   % object_format=proplist
#{}                  -> {}            -> #{}                        % object_format=map
#{key => val}        -> {"key":"val"} -> #{<<"key">> => <<"val">>}  % object_format=map

API

See EDoc Document

Benchmark

Environment/Method

  • OS: CentOS 6.5
  • CPU: Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz (x8)
  • Erlang/OTP: R17.1
  • Benchmark Tool: erl_json_test
  • CompileOption: [native, {hipe, [o3]}]

Target

Decode Result

  • column: module name
  • row: data size (bytes)
  • cell: elapsed time (micro seconds)
jiffy jsone jsonerl jsonx jsx mochijson2 yawsjson2
559 (1x) 12 11 61 7 50 28 37
1583 (3x) 24 25 66 15 134 68 84
4637 (9x) 65 86 178 36 410 186 311
13914 (27x) 189 271 533 109 1466 550 582
41542 (81x) 525 813 1578 299 4684 1599 1939
124726 (243x) 1549 2406 4709 852 14562 4799 6123

Encode Result

  • column: module name
  • row: data size (bytes)
  • cell: elapsed time (micro seconds)
jiffy jsone jsonerl jsonx jsx mochijson2 yawsjson2
559 (1x) 14 19 21 8 83 19 15
1583 (3x) 29 49 65 14 228 61 42
4637 (9x) 77 133 229 36 638 225 161
13914 (27x) 215 393 737 101 1993 664 435
41542 (81x) 621 1172 2058 300 6237 2310 1192
124726 (243x) 1830 3968 5842 828 17032 6979 5266