repeated keys ignored by default in jsx:json_to_term/1,2. option to ensure 'last key wins' behaviour

This commit is contained in:
alisdair sullivan 2011-08-17 19:33:59 -07:00
parent 6d6d61a817
commit 68ff87748c

View file

@ -30,7 +30,8 @@
-record(decoder_opts, { -record(decoder_opts, {
strict = false, strict = false,
encoding = auto encoding = auto,
repeatable_keys = true
}). }).
@ -113,6 +114,11 @@ parse_opts([{output_encoding, Val}|Rest], Opts = #encoder_opts{formatter_opts =
Val =:= utf16; Val =:= {utf16,little}; Val =:= utf16; Val =:= {utf16,little};
Val =:= utf32; Val =:= {utf32,little} -> Val =:= utf32; Val =:= {utf32,little} ->
parse_opts(Rest, Opts#encoder_opts{formatter_opts = [{output_encoding, Val}] ++ F}); parse_opts(Rest, Opts#encoder_opts{formatter_opts = [{output_encoding, Val}] ++ F});
parse_opts([{repeatable_keys, Val}|Rest], Opts = #decoder_opts{})
when Val =:= true; Val =:= false ->
parse_opts(Rest, Opts#decoder_opts{repeatable_keys = Val});
parse_opts([repeatable_keys|Rest], Opts = #decoder_opts{}) ->
parse_opts(Rest, Opts#decoder_opts{repeatable_keys = true});
parse_opts([], Opts) -> parse_opts([], Opts) ->
Opts. Opts.
@ -172,7 +178,7 @@ collect({jsx, incomplete, More}, _Acc, Opts) ->
collect([Event|Next], [Current|Rest], Opts) when is_list(Current) -> collect([Event|Next], [Current|Rest], Opts) when is_list(Current) ->
collect(Next, [[event(Event, Opts)] ++ Current] ++ Rest, Opts); collect(Next, [[event(Event, Opts)] ++ Current] ++ Rest, Opts);
%% delete any prior uses of current key %% delete any prior uses of current key
collect([Event|Next], [Key, Current|Rest], Opts) -> collect([Event|Next], [Key, Current|Rest], Opts=#decoder_opts{repeatable_keys=false}) ->
case proplists:is_defined(Key, Current) of case proplists:is_defined(Key, Current) of
true -> true ->
Acc = proplists:delete(Key, Current), Acc = proplists:delete(Key, Current),
@ -186,6 +192,8 @@ collect([Event|Next], [Key, Current|Rest], Opts) ->
Opts Opts
) )
end; end;
collect([Event|Next], [Key, Current|Rest], Opts) ->
collect(Next, [[{Key, event(Event, Opts)}] ++ Current] ++ Rest, Opts);
%% any other event is an error %% any other event is an error
collect(_, _, _) -> erlang:error(badarg). collect(_, _, _) -> erlang:error(badarg).
@ -434,19 +442,19 @@ encode_test_() ->
repeated_keys_test_() -> repeated_keys_test_() ->
[ [
{"simple repeated key", {"simple repeated key",
?_assert(json_to_term(<<"{\"a\":false,\"a\":true}">>, []) ?_assert(json_to_term(<<"{\"a\":false,\"a\":true}">>, [{repeatable_keys, false}])
=:= [{<<"a">>, true}] =:= [{<<"a">>, true}]
) )
}, },
{"nested repeated key", {"nested repeated key",
?_assert(json_to_term( ?_assert(json_to_term(
<<"[{\"a\":false,\"a\":true},{\"a\":false,\"a\":true}]">>, <<"[{\"a\":false,\"a\":true},{\"a\":false,\"a\":true}]">>,
[]) [{repeatable_keys, false}])
=:= [[{<<"a">>, true}], [{<<"a">>, true}]] =:= [[{<<"a">>, true}], [{<<"a">>, true}]]
) )
}, },
{"multiple keys", {"multiple keys",
?_assert(json_to_term(<<"{\"a\":4,\"a\":3,\"a\":2,\"a\":1}">>, []) ?_assert(json_to_term(<<"{\"a\":4,\"a\":3,\"a\":2,\"a\":1}">>, [{repeatable_keys, false}])
=:= [{<<"a">>, 1}] =:= [{<<"a">>, 1}]
) )
} }