JSONX is an Erlang library for efficient JSON decoding and encoding, implemented in Erlang NIFs. Works with binaries as strings, arrays as lists and only knows how to decode UTF-8 (and ASCII).
Check out a benchmark si14/erl_json_test or
davisp/erljson_bench and
record encoding tests in /test/bench_encode_records.erl
- cd jsonx
- make
- make doc
- firefox doc/index.html&
-module(record_example).
-compile(export_all).
-record(person, {name, age, friends}).
-record(person2, {name, age, phone}).
encoder1() ->jsonx:encoder([{person, record_info(fields, person)},
{person2, record_info(fields, person2)} ]).
decoder1() ->jsonx:decoder([{person, record_info(fields, person)},
{person2, record_info(fields, person2)}]).
nonstrict_decoder1() ->jsonx:decoder([{person, record_info(fields, person)},
{person2, record_info(fields, person2)}],
[{format, proplist}]).1>c(records_examples).
{ok,records_examples}
2>rr(record_examples).
[person,person2]
3>BabaYaga=#person2{name= <<"BabaYaga">>, age=118, phone= <<"666-66-66">>}.
#person2{name= <<"BabaYaga">>,age=118,
phone= <<"666-66-66">>}
4>Vasya=#person{name= <<"Vasya">>, age=18, friends= [BabaYaga]}.
#person{name= <<"Vasya">>,age=18,
friends= [#person2{name= <<"BabaYaga">>,age=118,
phone= <<"666-66-66">>}]}
5>Encoder=record_examples:encoder1().
#Fun<jsonx.0.45888425>6>Decoder=record_examples:decoder1().
#Fun<jsonx.1.21317315>7>Json=Encoder(BabaYaga).
<<"{\"name\": \"BabaYaga\",\"age\": 118,\"phone\": \"666-66-66\"}">>
8>Decoder(Json).
#person2{name= <<"BabaYaga">>,age=118,
phone= <<"666-66-66">>}
9>Json2=Encoder(Vasya).
<<"{\"name\": \"Vasya\",\"age\": 18,\"friends\": [{\"name\": \"BabaYaga\",\"age\": 118,\"phone\": \"666-66-66\"}]}">>
10>Decoder(Json2).
#person{name= <<"Vasya">>,age=18,
friends= [#person2{name= <<"BabaYaga">>,age=118,
phone= <<"666-66-66">>}]}
11>Json3= <<"[{\"name\": \"BabaYaga\",\"age\": 118,\"phone\": \"666-66-66\"}, {\"record\": \"undefined\", \"strict\": false}]">>.
<<"[{\"name\": \"BabaYaga\",\"age\": 118,\"phone\": \"666-66-66\"}, {\"record\": \"undefined\", \"strict\": false}]">>
12>Decoder(Json3).
{error,undefined_record,64}
13>NonStrictDecoder=record_examples:nonstrict_decoder1().
#Fun<jsonx.2.71844966>14>JTerm=NonStrictDecoder(Json3).
[#person2{name= <<"BabaYaga">>,age=118,
phone= <<"666-66-66">>},
[{<<"record">>,<<"undefined">>},{<<"strict">>,false}]]
15>Encoder(JTerm).
<<"[{\"name\": \"BabaYaga\",\"age\": 118,\"phone\": \"666-66-66\"},{\"record\":\"undefined\",\"strict\":false}]">>1>jsonx:encode([1, 2.3, true, false, null, atom, <<"string">>, []]).
<<"[1,2.3,true,false,null,\"atom\",\"string\",[]]">>
%% Object as proplist2>jsonx:encode( [{name, <<"Ivan">>}, {age, 33}, {phones, [3332211, 4443322]}] ).
<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>
%% Object as struct3>jsonx:encode( {struct, [{name, <<"Ivan">>}, {age, 33}, {phones, [3332211, 4443322]}]} ).
<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>
%% Object as eep18 propsal4>jsonx:encode( {[{name, <<"Ivan">>}, {age, 33}, {phones, [3332211, 4443322]}]} ).
<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>1>jsonx:decode(<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>).
{[{<<"name">>,<<"Ivan">>},
{<<"age">>,33},
{<<"phones">>,[3332211,4443322]}]}
2>jsonx:decode(<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>, [{format, eep18}]).
{[{<<"name">>,<<"Ivan">>},
{<<"age">>,33},
{<<"phones">>,[3332211,4443322]}]}
3>jsonx:decode(<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>, [{format, proplist}]).
[{<<"name">>,<<"Ivan">>},
{<<"age">>,33},
{<<"phones">>,[3332211,4443322]}]
4>jsonx:decode(<<"{\"name\":\"Ivan\",\"age\":33,\"phones\":[3332211,4443322]}">>, [{format, struct}]). {struct,[{<<"name">>,<<"Ivan">>},
{<<"age">>,33},
{<<"phones">>,[3332211,4443322]}]}More example see examples/stream_example.erl .
1>D=jstream:new_decoder(<<"{\"key1\": \"val1\",\n">>).
<<>>
2>jstream:get_event(D).
start_map3>jstream:get_event(D).
{map_key,<<"key1">>}
4>jstream:get_event(D).
<<"val1">>
5>jstream:get_event(D).
parse_buf6>ok=jstream:update_decoder(D, <<"\"key2\": \"val2\"}\n">>).
ok7>jstream:get_event(D).
{map_key,<<"key2">>}
8>jstream:get_event(D).
<<"val2">>
9>jstream:get_event(D).
end_map10>jstream:get_event(D).
{parse_end,<<>>}
null :-> null
true :-> true
false :-> false
"string" :-> <<"binary">>
[1, 2.3, []] :-> [1, 2.3, []]
{"this": "json"} :-> {[{<<"this">>: <<"json">>}]} %% default eep18
{"this": "json"} :-> [{<<"this">>: <<"json">>}] %% optional proplist
{"this": "json"} :-> {struct, [{<<"this">>: <<"json">>}]} %% optional struct
JSONObject :-> #rec{...} %% decoder must be predefined
null :-> null
true :-> true
false :-> false
atom :-> "atom"
<<"str">> :-> "str"
[1, 2.99] :-> [1, 2.99]
{struct, [{<<"this">>: <<"json">>}]} :-> {"this": "json"}
[{<<"this">>: <<"json">>}] :-> {"this": "json"}
{[{<<"this">>: <<"json">>}]} :-> {"this": "json"}
{json, IOList} :-> `iolist_to_binary(IOList)` %% include with no validation
#rec{...} :-> JSONObject %% encoder must be predefined