Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ to keep with the standard (rfc4627). Encoding is also compatible with rfc8259.
| number() | binary() | json_object() | json_array().
-type json_object() :: #{json_key() => json_value()}.
-type json_array() :: [json_value()].
-type json_opts() :: #{'keys' => 'atom' | 'existing_atom' | 'list'}.
-type json_opts() :: #{'keys' => 'atom' | 'existing_atom' | 'list' |
'integet_and_atom'}.

-spec lejson:decode(iodata()) -> json_object() | json_array() | {error, not_json}.
-spec lejson:decode(iodata(), json_opts()) ->
Expand Down
9 changes: 8 additions & 1 deletion src/lejson.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
| number() | binary() | json_object() | json_array().
-type json_object() :: #{json_key() => json_value()}.
-type json_array() :: [json_value()].
-type json_opts() :: #{'keys' => 'atom' | 'existing_atom' | 'list'}.
-type json_opts() :: #{'keys' => 'atom' | 'existing_atom' | 'list' |
'integer_and_atom' }.

%% Encode ---------------------------------------------------------------------

Expand Down Expand Up @@ -52,6 +53,7 @@ encode_value(#{} = Map) -> encode_map(Map);
encode_value(Array) when is_list(Array) -> encode_array(Array).

encode_key(Key) when is_atom(Key) -> atom_to_binary(Key, utf8);
encode_key(Key) when is_integer(Key) -> integer_to_binary(Key);
encode_key(Key) -> Key.

encode_string(Bin) when is_binary(Bin) ->
Expand Down Expand Up @@ -257,4 +259,9 @@ is_json(_) -> false.
convert_key(Key, #{keys:=atom}) -> binary_to_atom(Key, utf8);
convert_key(Key, #{keys:=existing_atom}) -> binary_to_existing_atom(Key, utf8);
convert_key(Key, #{keys:=list}) -> binary_to_list(Key);
convert_key(Key, #{keys:=integer_and_atom}) ->
try binary_to_integer(Key)
catch
_:_ -> binary_to_atom(Key, utf8)
end;
convert_key(Key, #{}) -> Key.
29 changes: 23 additions & 6 deletions test/lejson_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ config_test_() ->
fun setup_config/0,
fun cleanup_config/1,
{inorder, [ {timeout, 120,
{"encode", fun() -> test_encode({e,n,c}) end}} |
[ {timeout, 120,
{atom_to_list(Name),
fun() -> test_decode(Data) end}} ||
{Name,_,_} = Data <- json_strings_should_pass()]]}}.
{"encode", fun() -> test_encode({e,n,c}) end}},
[ {timeout, 120,
{atom_to_list(Name),
fun() -> test_opts(Data) end}} ||
{Name,_,_,_} = Data <- maps_with_opts()],
[ {timeout, 120,
{atom_to_list(Name),
fun() -> test_decode(Data) end}} ||
{Name,_,_} = Data <- json_strings_should_pass()]]}}.

setup_config() -> ok.
cleanup_config(_) -> ok.
Expand Down Expand Up @@ -82,8 +86,15 @@ json_strings_should_pass() ->
<<"{\"escaped_string\": \"\\t\\n\\r\\f\\b\\\\\\/\\\"\"}">>,
#{<<"escaped_string">> => <<"\t\n\r\f\b\\/\"">>}}].

maps_with_opts() ->
[{integer_as_key,
<<"{\"256\": 1}">>,
#{256 => 1}, #{keys => integer_and_atom}}].

test_decode({_Type, Data, Expected}) ->
?assertEqual(Expected, lejson:decode(Data)).
?assertEqual(Expected, lejson:decode(Data));
test_decode({_Type, Data, Expected, Opts}) ->
?assertEqual(Expected, lejson:decode(Data, Opts)).

test_encode({_Type, _Data, _Expected}) ->
test_encode_decode(simple_json()).
Expand All @@ -108,3 +119,9 @@ simple_json() ->
"\"nested_array\": [[[79]]],"
"\"another_array\": [1,2,3,[1,[2],3],12]}">>.

test_opts({_Type, ExpectedJson, Map, Opts}) ->
Json = lejson:encode(Map),
NewMap = lejson:decode(Json, Opts),
Json == ExpectedJson andalso
Map == NewMap.