use end_json to end streaming when in streaming mode in addition

to `end_stream`
This commit is contained in:
alisdair sullivan 2014-08-13 23:00:35 -07:00
parent b14714aef9
commit c25bb49902
5 changed files with 38 additions and 7 deletions

View file

@ -1,3 +1,7 @@
v2.1
* force the end of streams with `end_json` in addition to `end_stream`
v2.0.4
* more typespec adjustments

View file

@ -264,16 +264,16 @@ memory
however, it is important to recognize that **jsx** is conservative by default. **jsx** will
not consider the parsing complete even when input is exhausted and the json text is
unambiguously incomplete. to end parsing call the `incomplete` function with the
argument `end_stream` like:
argument `end_stream` (or `end_json`) like:
```erlang
1> {incomplete, F} = jsx:decode(<<"[">>, [stream]).
{incomplete,#Fun<jsx_decoder.1.122947756>}
2> F(end_stream).
2> F(end_stream). % can also be `F(end_json)`
** exception error: bad argument
3> {incomplete, G} = F(<<"]">>).
{incomplete,#Fun<jsx_decoder.1.122947756>}
4> G(end_stream).
4> G(end_stream). % can also be `G(end_json)`
[]
```

View file

@ -107,14 +107,14 @@ is_term(Source) -> is_term(Source, []).
is_term(Source, Config) -> jsx_verify:is_term(Source, Config).
-type decoder() :: fun((json_text() | end_stream) -> any()).
-type decoder() :: fun((json_text() | end_stream | end_json) -> any()).
-spec decoder(Handler::module(), State::any(), Config::list()) -> decoder().
decoder(Handler, State, Config) -> jsx_decoder:decoder(Handler, State, Config).
-type encoder() :: fun((json_term() | end_stream) -> any()).
-type encoder() :: fun((json_term() | end_stream | end_json) -> any()).
-spec encoder(Handler::module(), State::any(), Config::list()) -> encoder().
@ -464,5 +464,32 @@ encode_test_() ->
} || {Title, _, Term, Events} <- Data
].
end_stream_test_() ->
Tokens = [start_object, end_object, end_json],
[
{"encoder end_stream", ?_assertEqual(
Tokens,
begin
{incomplete, F} = (jsx:parser(jsx, [], [stream]))([start_object, end_object]),
F(end_stream)
end
)},
{"encoder end_json", ?_assertEqual(
Tokens,
begin
{incomplete, F} = (jsx:parser(jsx, [], [stream]))([start_object, end_object]),
F(end_json)
end
)},
{"decoder end_stream", ?_assertEqual(
Tokens,
begin {incomplete, F} = (jsx:decoder(jsx, [], [stream]))(<<"{}">>), F(end_stream) end
)},
{"decoder end_json", ?_assertEqual(
Tokens,
begin {incomplete, F} = (jsx:decoder(jsx, [], [stream]))(<<"{}">>), F(end_json) end
)}
].
-endif.

View file

@ -150,7 +150,7 @@ incomplete(State, Rest, Handler, Acc, Stack, Config = #config{stream=false}) ->
incomplete(State, Rest, Handler, Acc, Stack, Config = #config{incomplete_handler=false}) ->
{incomplete, fun(Stream) when is_binary(Stream) ->
resume(<<Rest/binary, Stream/binary>>, State, Handler, Acc, Stack, Config);
(end_stream) ->
(End) when End == end_stream; End == end_json ->
case resume(<<Rest/binary, ?space/utf8>>, State, Handler, Acc, Stack, Config#config{stream=false}) of
{incomplete, _} -> ?error(State, Rest, Handler, Acc, Stack, Config);
Else -> Else

View file

@ -71,7 +71,7 @@ resume(Rest, State, Handler, Stack, Config) ->
incomplete(State, Handler, Stack, Config=#config{stream=false}) ->
?error(State, [], Handler, Stack, Config);
incomplete(State, Handler, Stack, Config=#config{incomplete_handler=false}) ->
{incomplete, fun(end_stream) ->
{incomplete, fun(End) when End == end_stream; End == end_json ->
case resume([end_json], State, Handler, Stack, Config) of
{incomplete, _} -> ?error(State, [], Handler, Stack, Config);
Else -> Else