Need help with jsone?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

sile
229 Stars 51 Forks MIT License 217 Commits 0 Opened issues

Description

Erlang JSON library

Services available

!
?

Need anything else?

Contributors list

# 53,718
Erlang
gzip
zlib
hyperpa...
148 commits
# 352,395
Erlang
Elixir
java-8
The Jul...
11 commits
# 18,219
pony-la...
Apache ...
gRPC
doge
5 commits
# 560,495
raku
ecosyst...
Erlang
3 commits
# 690,307
Erlang
3 commits
# 6,834
Erlang
HTTP
Python
faceboo...
3 commits
# 78,463
Erlang
kafka
rust-cr...
pony-la...
3 commits
# 347,475
TeX
Shell
Erlang
2 commits
# 289,921
Swift
Erlang
custom-...
carthag...
2 commits
# 11,478
Erlang
kafka
postgre...
mqtt-se...
1 commit
# 160,601
Erlang
garmin
Racket
MongoDB
1 commit
# 97,743
Erlang
hadoop
cupy
s3
1 commit
# 21,996
C
Perl
Rails
Qt
1 commit
# 396,678
Erlang
Elixir
kafka
compile
1 commit

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 <>

%% If you want to safely cast object keys to atoms, the `attempt_atom' option will help. > jsone:decode(<>, [{keys, attempt_atom}]). #{<> => <>} % There is no atom named "hello", so the key is decoded as binary.

> hello. % Create "hello" atom. hello

> jsone:decode(<>, [{keys, attempt_atom}]). #{hello => <>} % Now, the key is decoded as atom.

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.