From 1da0c567ba2fe20eb08897bbc485a8d6cda106f4 Mon Sep 17 00:00:00 2001 From: John Daily Date: Wed, 3 Jul 2013 21:51:26 -0400 Subject: [PATCH] Add sloppy_existing_atom as a configuration option for labels --- README.md | 16 +++++++++------- src/jsx_to_term.erl | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b723ec5b..4cdacc69 100644 --- a/README.md +++ b/README.md @@ -467,18 +467,20 @@ decode(JSON, Opts) -> Term JSON = json_text() Term = json_term() Opts = [option() | labels | {labels, Label} | {post_decode, F}] - Label = binary | atom | existing_atom + Label = binary | atom | existing_atom | sloppy_existing_atom F = fun((any()) -> any()) ``` `decode` parses a json text (a `utf8` encoded binary) and produces an erlang term -the option `labels` controls how keys are converted from json to erlang terms. -`binary` does no conversion beyond normal escaping. `atom` converts keys to -erlang atoms and results in a badarg error if the keys fall outside the range of -erlang atoms. `existing_atom` is identical to `atom` except it will not add new -atoms to the atom table +the option `labels` controls how keys are converted from json to +erlang terms. `binary` (the default behavior) does no conversion +beyond normal escaping. `atom` converts keys to erlang atoms and +results in a badarg error if the keys fall outside the range of erlang +atoms. `existing_atom` is identical to `atom` except it will not add +new atoms to the atom table. `sloppy_existing_atom` will convert keys +to atoms when they exist, and leave them as binary otherwise `{post_decode, F}` is a user defined function of arity 1 that is called on each output value (objects, arrays, strings, numbers and literals). it may return any @@ -709,4 +711,4 @@ jsx wouldn't be what it is without the contributions of [paul davis](https://git [rebar]: https://github.com/rebar/rebar [meck]: https://github.com/eproxus/meck [rfc4627]: http://tools.ietf.org/html/rfc4627 -[travis]: https://travis-ci.org/ \ No newline at end of file +[travis]: https://travis-ci.org/ diff --git a/src/jsx_to_term.erl b/src/jsx_to_term.erl index 90515add..828073d3 100644 --- a/src/jsx_to_term.erl +++ b/src/jsx_to_term.erl @@ -53,7 +53,7 @@ to_term(Source, Config) when is_list(Config) -> parse_config(Config) -> parse_config(Config, #config{}). parse_config([{labels, Val}|Rest], Config) - when Val == binary; Val == atom; Val == existing_atom -> + when Val == binary; Val == atom; Val == existing_atom; Val == sloppy_existing_atom -> parse_config(Rest, Config#config{labels = Val}); parse_config([labels|Rest], Config) -> parse_config(Rest, Config#config{labels = binary}); @@ -107,6 +107,12 @@ format_key(Key, Config) -> binary -> Key ; atom -> binary_to_atom(Key, utf8) ; existing_atom -> binary_to_existing_atom(Key, utf8) + ; sloppy_existing_atom -> + try binary_to_existing_atom(Key, utf8) of + Result -> Result + catch + error:badarg -> Key + end end. @@ -133,6 +139,10 @@ config_test_() -> #config{labels=existing_atom}, parse_config([{labels, existing_atom}]) )}, + {"sloppy existing atom labels", ?_assertEqual( + #config{labels=sloppy_existing_atom}, + parse_config([{labels, sloppy_existing_atom}]) + )}, {"post decode", ?_assertEqual( #config{post_decode=F}, parse_config([{post_decode, F}]) @@ -154,6 +164,14 @@ format_key_test_() -> {"nonexisting atom key", ?_assertError( badarg, format_key(<<"nonexistentatom">>, #config{labels=existing_atom}) + )}, + {"sloppy existing atom key", ?_assertEqual( + key, + format_key(<<"key">>, #config{labels=sloppy_existing_atom}) + )}, + {"nonexisting atom key", ?_assertEqual( + <<"nonexistentatom">>, + format_key(<<"nonexistentatom">>, #config{labels=sloppy_existing_atom}) )} ].