is_json rewritten to use new api
This commit is contained in:
parent
39605da171
commit
bb80bf2b83
1 changed files with 41 additions and 47 deletions
|
@ -38,21 +38,20 @@
|
||||||
; (F::jsx_iterator(), Opts::verify_opts()) -> true | false.
|
; (F::jsx_iterator(), Opts::verify_opts()) -> true | false.
|
||||||
|
|
||||||
is_json(JSON, OptsList) when is_binary(JSON) ->
|
is_json(JSON, OptsList) when is_binary(JSON) ->
|
||||||
P = jsx:decoder([iterate] ++ extract_parser_opts(OptsList)),
|
F = jsx:decoder(extract_parser_opts(OptsList)),
|
||||||
is_json(fun() -> P(JSON) end, OptsList);
|
verify(F(JSON), parse_opts(OptsList));
|
||||||
is_json(Terms, OptsList) when is_list(Terms) ->
|
is_json(JSON, OptsList) when is_list(JSON) ->
|
||||||
P = jsx:encoder([iterate]),
|
try
|
||||||
is_json(fun() -> P(Terms) end, OptsList);
|
F = jsx:encoder(extract_parser_opts(OptsList)),
|
||||||
|
verify(F(JSON), parse_opts(OptsList))
|
||||||
|
catch
|
||||||
|
_:_ -> erlang:error(badarg)
|
||||||
|
end;
|
||||||
is_json(F, OptsList) when is_function(F) ->
|
is_json(F, OptsList) when is_function(F) ->
|
||||||
Opts = parse_opts(OptsList, #verify_opts{}),
|
try
|
||||||
case Opts#verify_opts.naked_values of
|
verify(jsx_utils:collect(F), parse_opts(OptsList))
|
||||||
true -> collect(F(), Opts, [[]])
|
catch
|
||||||
; false ->
|
_:_ -> erlang:error(badarg)
|
||||||
case F() of
|
|
||||||
{jsx, start_object, Next} -> collect(Next(), Opts, [[]])
|
|
||||||
; {jsx, start_array, Next} -> collect(Next(), Opts, [[]])
|
|
||||||
; _ -> false
|
|
||||||
end
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +71,8 @@ extract_parser_opts([K|Rest], Acc) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
parse_opts(Opts) -> parse_opts(Opts, #verify_opts{}).
|
||||||
|
|
||||||
parse_opts([{repeated_keys, Val}|Rest], Opts) ->
|
parse_opts([{repeated_keys, Val}|Rest], Opts) ->
|
||||||
parse_opts(Rest, Opts#verify_opts{repeated_keys = Val});
|
parse_opts(Rest, Opts#verify_opts{repeated_keys = Val});
|
||||||
parse_opts([repeated_keys|Rest], Opts) ->
|
parse_opts([repeated_keys|Rest], Opts) ->
|
||||||
|
@ -80,51 +81,44 @@ parse_opts([{naked_values, Val}|Rest], Opts) ->
|
||||||
parse_opts(Rest, Opts#verify_opts{naked_values = Val});
|
parse_opts(Rest, Opts#verify_opts{naked_values = Val});
|
||||||
parse_opts([naked_values|Rest], Opts) ->
|
parse_opts([naked_values|Rest], Opts) ->
|
||||||
parse_opts(Rest, Opts#verify_opts{naked_values = true});
|
parse_opts(Rest, Opts#verify_opts{naked_values = true});
|
||||||
parse_opts([_|Rest], Opts) ->
|
parse_opts([{encoding, _}|Rest], Opts) ->
|
||||||
|
parse_opts(Rest, Opts);
|
||||||
|
parse_opts([encoding|Rest], Opts) ->
|
||||||
parse_opts(Rest, Opts);
|
parse_opts(Rest, Opts);
|
||||||
parse_opts([], Opts) ->
|
parse_opts([], Opts) ->
|
||||||
Opts.
|
Opts.
|
||||||
|
|
||||||
|
|
||||||
|
verify({error, {badjson, _}}, _Opts) -> false;
|
||||||
|
verify({jsx, incomplete, More}, Opts) -> verify(More(end_stream), Opts);
|
||||||
|
verify({jsx, [First|Rest], _}, Opts=#verify_opts{naked_values=false}) ->
|
||||||
|
case First of
|
||||||
|
start_object -> verify(Rest, Opts, [])
|
||||||
|
; start_array -> verify(Rest, Opts, [])
|
||||||
|
; _ -> false
|
||||||
|
end;
|
||||||
|
verify({jsx, Terms, _}, Opts) -> verify(Terms, Opts, []).
|
||||||
|
|
||||||
collect({jsx, end_json, _Next}, _Opts, _Keys) ->
|
|
||||||
true;
|
|
||||||
|
|
||||||
|
verify([end_json], _Opts, _Keys) -> true;
|
||||||
|
|
||||||
%% allocate new key accumulator at start_object, discard it at end_object
|
%% allocate new key accumulator at start_object, discard it at end_object
|
||||||
collect({jsx, start_object, Next},
|
verify([start_object|Rest], Opts=#verify_opts{repeated_keys=false}, Keys) ->
|
||||||
Opts = #verify_opts{repeated_keys = false},
|
verify(Rest, Opts, [[]] ++ Keys);
|
||||||
Keys) ->
|
verify([end_object|Rest], Opts=#verify_opts{repeated_keys=false}, [_|Keys]) ->
|
||||||
collect(Next(), Opts, [[]|Keys]);
|
verify(Rest, Opts, Keys);
|
||||||
collect({jsx, end_object, Next},
|
|
||||||
Opts = #verify_opts{repeated_keys = false},
|
|
||||||
[_|Keys]) ->
|
|
||||||
collect(Next(), Opts, [Keys]);
|
|
||||||
|
|
||||||
|
|
||||||
%% check to see if key has already been encountered, if not add it to the key
|
%% check to see if key has already been encountered, if not add it to the key
|
||||||
%% accumulator and continue, else return false
|
%% accumulator and continue, else return false
|
||||||
collect({jsx, {key, Key}, Next},
|
verify([{key, Key}|Rest], Opts=#verify_opts{repeated_keys=false}, [Current|Keys]) ->
|
||||||
Opts = #verify_opts{repeated_keys = false},
|
|
||||||
[Current|Keys]) ->
|
|
||||||
case lists:member(Key, Current) of
|
case lists:member(Key, Current) of
|
||||||
true -> false
|
true -> false
|
||||||
; false -> collect(Next(), Opts, [[Key] ++ Current] ++ Keys)
|
; false -> verify(Rest, Opts, [[Key] ++ Current] ++ Keys)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
%% needed to parse numbers that don't have trailing whitespace in less strict
|
|
||||||
%% mode
|
|
||||||
collect({jsx, incomplete, More}, Opts, Keys) ->
|
|
||||||
collect(More(end_stream), Opts, Keys);
|
|
||||||
|
|
||||||
|
|
||||||
collect({jsx, _, Next}, Opts, Keys) ->
|
verify([_|Rest], Opts, Keys) -> verify(Rest, Opts, Keys);
|
||||||
collect(Next(), Opts, Keys);
|
|
||||||
|
|
||||||
|
verify(_, _, _) -> false.
|
||||||
collect(_, _, _) ->
|
|
||||||
false.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,16 +162,16 @@ true_test_() ->
|
||||||
},
|
},
|
||||||
{"nested objects",
|
{"nested objects",
|
||||||
?_assert(is_json(<<"{\"key\": { \"key\": true}}">>, []) =:= true)
|
?_assert(is_json(<<"{\"key\": { \"key\": true}}">>, []) =:= true)
|
||||||
|
},
|
||||||
|
{"naked true", ?_assert(is_json(<<"true">>, []) =:= true)},
|
||||||
|
{"naked number", ?_assert(is_json(<<"1">>, []) =:= true)},
|
||||||
|
{"naked string",
|
||||||
|
?_assert(is_json(<<"\"i am not really json\"">>, []) =:= true)
|
||||||
}
|
}
|
||||||
].
|
].
|
||||||
|
|
||||||
false_test_() ->
|
false_test_() ->
|
||||||
[
|
[
|
||||||
{"naked true", ?_assert(is_json(<<"true">>, []) =:= true)},
|
|
||||||
{"naked number", ?_assert(is_json(<<"1">>, []) =:= true)},
|
|
||||||
{"naked string",
|
|
||||||
?_assert(is_json(<<"\"i am not really json\"">>, []) =:= true)
|
|
||||||
},
|
|
||||||
{"unbalanced list", ?_assert(is_json(<<"[[[]]">>, []) =:= false)},
|
{"unbalanced list", ?_assert(is_json(<<"[[[]]">>, []) =:= false)},
|
||||||
{"trailing comma",
|
{"trailing comma",
|
||||||
?_assert(is_json(<<"[ true, false, null, ]">>, []) =:= false)
|
?_assert(is_json(<<"[ true, false, null, ]">>, []) =:= false)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue