From 76723ce73675342c79457ca6725b587f47dfdd6f Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Fri, 6 Apr 2012 08:09:52 -0700 Subject: [PATCH] semantic change to way pre_encode works --- README.markdown | 6 +++--- src/jsx_encoder.erl | 33 ++++++--------------------------- src/jsx_opts.hrl | 2 +- src/jsx_utils.erl | 21 ++++++++++++--------- 4 files changed, 22 insertions(+), 40 deletions(-) diff --git a/README.markdown b/README.markdown index a90a1a6f..2900d5d5 100644 --- a/README.markdown +++ b/README.markdown @@ -147,11 +147,11 @@ this option treats all exhausted inputs as incomplete, as explained below. the p relax is a synonym for `[replaced_bad_utf8, single_quoted_strings, comments, ignored_bad_escapes]` for when you don't care how janky and awful your json input is, you just want the parser to do the best it can -#### `{pre_encoder, F}` or `{pre_encoders, [F, G,...]}` #### +#### `{pre_encode, F}` #### -pre encoders are functions of arity 1 that pre-process input to the encoder. only input evaluated in a *value* context is pre-processed in this manner (so keys are not pre-processed, but objects and lists are). if more than one pre encoder is declared, the input will be passed to each of them in the order they are declared +`F` is a function of arity 1 that pre-process input to the encoder. only input evaluated in a *value* context is pre-processed in this manner (so keys are not pre-processed, but objects and arrays are). if more than one pre encoder is declared, a `badarg` exception will occur -input can be any term, but final output from the chain should be otherwise recognized input to the encoder +input can be any term, but output from the function must be a valid type for input ### incomplete input ### diff --git a/src/jsx_encoder.erl b/src/jsx_encoder.erl index cd2a08c6..53027128 100644 --- a/src/jsx_encoder.erl +++ b/src/jsx_encoder.erl @@ -99,7 +99,8 @@ list([], {Handler, State}, _Opts) -> Handler:handle_event(end_array, State); list(Term, Handler, Opts) -> ?error([Term, Handler, Opts]). -pre_encode(Value, Opts) -> lists:foldl(fun(F, V) -> F(V) end, Value, Opts#opts.pre_encoders). +pre_encode(Value, #opts{pre_encode=false}) -> Value; +pre_encode(Value, Opts) -> (Opts#opts.pre_encode)(Value). fix_key(Key) when is_atom(Key) -> fix_key(atom_to_binary(Key, utf8)); @@ -812,7 +813,7 @@ pre_encoders_test_() -> ] )}, {"replace lists with empty lists", ?_assertEqual( - encode(Term, [{pre_encoder, fun(V) -> case V of [{_,_}|_] -> V; [{}] -> V; V when is_list(V) -> []; _ -> V end end}]), + encode(Term, [{pre_encode, fun(V) -> case V of [{_,_}|_] -> V; [{}] -> V; V when is_list(V) -> []; _ -> V end end}]), [ start_object, {key, <<"object">>}, start_object, @@ -825,7 +826,7 @@ pre_encoders_test_() -> ] )}, {"replace objects with empty objects", ?_assertEqual( - encode(Term, [{pre_encoder, fun(V) -> case V of [{_,_}|_] -> [{}]; _ -> V end end}]), + encode(Term, [{pre_encode, fun(V) -> case V of [{_,_}|_] -> [{}]; _ -> V end end}]), [ start_object, end_object, @@ -833,7 +834,7 @@ pre_encoders_test_() -> ] )}, {"replace all non-list values with false", ?_assertEqual( - encode(Term, [{pre_encoder, fun(V) when is_list(V) -> V; (_) -> false end}]), + encode(Term, [{pre_encode, fun(V) when is_list(V) -> V; (_) -> false end}]), [ start_object, {key, <<"object">>}, start_object, @@ -852,7 +853,7 @@ pre_encoders_test_() -> ] )}, {"replace all atoms with atom_to_list", ?_assertEqual( - encode(Term, [{pre_encoder, fun(V) when is_atom(V) -> unicode:characters_to_binary(atom_to_list(V)); (V) -> V end}]), + encode(Term, [{pre_encode, fun(V) when is_atom(V) -> unicode:characters_to_binary(atom_to_list(V)); (V) -> V end}]), [ start_object, {key, <<"object">>}, start_object, @@ -869,28 +870,6 @@ pre_encoders_test_() -> end_object, end_json ] - )}, - {"replace all atoms to strings and back", ?_assertEqual( - encode(Term, [{pre_encoders, [ - fun(V) when is_atom(V) -> unicode:characters_to_binary(atom_to_list(V)); (V) -> V end, - fun(<<"true">>) -> true; (<<"false">>) -> false; (<<"null">>) -> null; (V) -> V end - ]}]), - [ - start_object, - {key, <<"object">>}, start_object, - {key, <<"literals">>}, start_array, - {literal, true}, {literal, false}, {literal, null}, - end_array, - {key, <<"strings">>}, start_array, - {string, <<"foo">>}, {string, <<"bar">>}, {string, <<"baz">>}, - end_array, - {key, <<"numbers">>}, start_array, - {integer, 1}, {float, 1.0}, {float, 1.0}, - end_array, - end_object, - end_object, - end_json - ] )} ]. diff --git a/src/jsx_opts.hrl b/src/jsx_opts.hrl index 625c737f..6b3de909 100644 --- a/src/jsx_opts.hrl +++ b/src/jsx_opts.hrl @@ -8,5 +8,5 @@ dirty_strings = false, ignored_bad_escapes = false, explicit_end = false, - pre_encoders = [] + pre_encode = false }). \ No newline at end of file diff --git a/src/jsx_utils.erl b/src/jsx_utils.erl index a889cb57..d4dfd41d 100644 --- a/src/jsx_utils.erl +++ b/src/jsx_utils.erl @@ -61,14 +61,17 @@ parse_opts([relax|Rest], Opts) -> comments = true, ignored_bad_escapes = true }); -parse_opts([{pre_encoder, Encoder}|Rest], Opts) when is_function(Encoder, 1) -> - AllEncoders = Opts#opts.pre_encoders ++ [Encoder], - parse_opts(Rest, Opts#opts{pre_encoders=AllEncoders}); -parse_opts([{pre_encoders, Encoders}|Rest], Opts) when is_list(Encoders) -> - lists:foreach(fun(F) when is_function(F, 1) -> ok end, Encoders), - AllEncoders = Opts#opts.pre_encoders ++ Encoders, - parse_opts(Rest, Opts#opts{pre_encoders=AllEncoders}); +parse_opts([{pre_encode, Encoder}|Rest] = Options, Opts) when is_function(Encoder, 1) -> + case Opts#opts.pre_encode of + false -> parse_opts(Rest, Opts#opts{pre_encode=Encoder}) + ; _ -> erlang:error(badarg, [Options, Opts]) + end; %% deprecated flags +parse_opts([{pre_encoder, Encoder}|Rest] = Options, Opts) when is_function(Encoder, 1) -> + case Opts#opts.pre_encode of + false -> parse_opts(Rest, Opts#opts{pre_encode=Encoder}) + ; _ -> erlang:error(badarg, [Options, Opts]) + end; parse_opts([loose_unicode|Rest], Opts) -> parse_opts(Rest, Opts#opts{replaced_bad_utf8=true}); parse_opts([escape_forward_slash|Rest], Opts) -> @@ -97,9 +100,9 @@ valid_flags() -> ignored_bad_escapes, explicit_end, relax, - pre_encoder, - pre_encoders, + pre_encode, %% deprecated flags + pre_encoder, %% pre_encode loose_unicode, %% replaced_bad_utf8 escape_forward_slash, %% escaped_forward_slashes single_quotes, %% single_quotes_strings