jsone

by sile

sile / jsone

Erlang JSON library

211 Stars 46 Forks Last release: Not found MIT License 201 Commits 47 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

jsone

hex.pm version Build Status Code Coverage License: MIT

An Erlang library for encoding, decoding JSON data.

Features

  • Provides simple encode/decode function only
  • RFC7159-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

compile

$ make compile

run tests

$ make eunit

dialyze

$ make dialyze

Erlang shell

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

Enable HiPE

If you want to use HiPE compiled version, please add following code to your rebar.config.

{overrides,
  [
    {override, jsone, [{erl_opts, [{d, 'ENABLE_HIPE'}, inline]}]}
  ]}.

or use

native
profile. The
make
command supports profile as well. For example:
$ make start profile=native

Usage Example

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

> jsone:decode(<>). #{<> => 2}

> jsone:decode(<>, [{object_format, tuple}]). % tuple format {[{<>, 2}]}

> jsone:decode(<>, [{object_format, proplist}]). % proplist format [{<>, 2}]

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

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

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

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

> jsone:encode(#{<> => <>}). % map format > jsone:encode({[{<>, <>}]}). % tuple format > jsone:encode([{<>, <>}]). % proplist format <>

> jsone:encode(#{key => <>}). % atom key is allowed <>

% error: raises exception > jsone:encode(#{123 => <>}). % 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,<>}],[],<>) in call from jsone:encode/1 (src/jsone.erl, line 97)

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

% 'object_key_type' option allows non-string object key > jsone:encode({[{123, <>}]}, [{object_key_type, scalar}]). <>

% 'undefined_as_null' option allows encoding atom undefined as null > jsone:encode(undefined,[undefined_as_null]). <>

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

%% Number Format > jsone:encode(1). % integer <>

> jsone:encode(1.23). % float <> % default: scientific notation

> jsone:encode(1.23, [{float_format, [{decimals, 4}]}]). % decimal notation <>

> jsone:encode(1.23, [{float_format, [{decimals, 4}, compact]}]). % compact decimal notation <>

Data Mapping (Erlang <=> JSON)

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

null -> null -> null undefined -> null -> undefined % undefined_as_null true -> true -> true false -> false -> false <> -> "abc" -> <> abc -> "abc" -> <> % non-special atom is regarded as a binary {{2010,1,1},{0,0,0}} -> "2010-01-01T00:00:00Z" -> <> % datetime* {{2010,1,1},{0,0,0.0}} -> "2010-01-01T00:00:00.000Z" -> <> % datetime* 123 -> 123 -> 123 123.4 -> 123.4 -> 123.4 [1,2,3] -> [1,2,3] -> [1,2,3] {[]} -> {} -> {[]} % object_format=tuple {[{key, <>}]} -> {"key":"val"} -> {[{<>, <>}]} % object_format=tuple [{}] -> {} -> [{}] % object_format=proplist [{<>, val}] -> {"key":"val"} -> [{<>, <>}] % object_format=proplist #{} -> {} -> #{} % object_format=map #{key => val} -> {"key":"val"} -> #{<> => <>} % object_format=map {{json, IOList}} -> Value -> ~ % UTF-8 encoded term** {{json_utf8, Chars}} -> Value -> ~ % Unicode code points**

* see jsone:datetimeencodeformat()

**

{json, IOList}
and
{json_utf8, Chars}
allows inline already encoded JSON values. For example, you obtain JSON encoded data from database so you don't have to decode it first and encode again. See jsone:json_term().

API

See EDoc Document

Benchmark

The results of poison benchmarking.

See the BENCHMARK.md file for more information.

EncoderBench Result

Non HiPE:

| | jiffy | jsone | poison | jazz | jsx | |:-----------------|-------------:|------------------:|--------------:|--------------:|--------------:| | maps | 7.23 μs/op | 10.64 μs/op (2) | 13.58 μs/op | 19.30 μs/op | 29.28 μs/op | | lists | 210.40 μs/op | 157.39 μs/op (3) | 109.30 μs/op | 201.82 μs/op | 357.25 μs/op | | strings* | 98.80 μs/op | 595.63 μs/op (5) | 416.78 μs/op | 399.89 μs/op | 262.18 μs/op | | string escaping* | 144.01 μs/op | 732.44 μs/op (2) | 1318.82 μs/op | 1197.06 μs/op | 1324.04 μs/op | | large value** | 408.03 μs/op | 1556.85 μs/op (3) | 1447.71 μs/op | 1824.05 μs/op | 2184.59 μs/op | | pretty print** | 420.94 μs/op | 1686.55 μs/op (3) | 1534.74 μs/op | 2041.22 μs/op | 5533.04 μs/op |

HiPE:

| | jiffy | jsone | poison | jazz | jsx | |:-----------------|-------------:|------------------:|--------------:|--------------:|--------------:| | maps | 7.69 μs/op | 6.12 μs/op (1) | 12.32 μs/op | 22.90 μs/op | 27.03 μs/op | | lists | 207.75 μs/op | 69.93 μs/op (1) | 79.04 μs/op | 229.95 μs/op | 278.01 μs/op | | strings* | 96.67 μs/op | 321.69 μs/op (5) | 142.43 μs/op | 310.10 μs/op | 179.96 μs/op | | string escaping* | 146.85 μs/op | 317.10 μs/op (2) | 1277.54 μs/op | 1311.85 μs/op | 767.67 μs/op | | large value** | 409.73 μs/op | 664.34 μs/op (2) | 806.24 μs/op | 1630.21 μs/op | 1777.62 μs/op | | pretty print** | 419.55 μs/op | 724.28 μs/op (2) | 844.76 μs/op | 1888.71 μs/op | 4872.34 μs/op |

* binary representation of UTF-8-demo.txt
** generated.json

ParserBench Result

Non HiPE:

| | jiffy | jsone | poison | jsx | |:-------------------|-------------:|------------------:|--------------:|--------------:| | json value* | 544.84 μs/op | 1364.38 μs/op (2) | 1401.35 μs/op | 1844.55 μs/op | | UTF-8 unescaping** | 63.01 μs/op | 399.38 μs/op (4) | 249.70 μs/op | 281.84 μs/op |

HiPE:

| | jiffy | jsone | poison | jsx | |:-------------------|-------------:|------------------:|--------------:|--------------:| | json value* | 542.77 μs/op | 561.15 μs/op (2) | 751.36 μs/op | 1435.10 μs/op | | UTF-8 unescaping** | 62.42 μs/op | 92.63 μs/op (2) | 118.97 μs/op | 172.07 μs/op |

* generated.json
** UTF-8-demo.txt

License

This library is released under the MIT License.

See the COPYING file for full license information.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.