From 1c5f54574c281f59d2b78efd2178b20d097a656c Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Wed, 26 May 2010 06:31:15 -0700 Subject: [PATCH] reduced redundancy in callback handling, also renamed callback function to the more clear fold --- src/jsx.erl | 5 ++- src/jsx_decoder.erl | 93 ++++++++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/jsx.erl b/src/jsx.erl index a69e2e5..e2aeffc 100644 --- a/src/jsx.erl +++ b/src/jsx.erl @@ -36,9 +36,12 @@ decoder(Opts) -> F = fun(eof, State) -> lists:reverse(State) ;(Event, State) -> [Event] ++ State end, decoder({F, []}, Opts). -decoder(Callbacks, OptsList) when is_list(OptsList) -> +decoder({F, _} = Callbacks, OptsList) when is_list(OptsList), is_function(F) -> Opts = parse_opts(OptsList), decoder(Callbacks, Opts); +decoder({{Mod, Fun}, State}, OptsList) when is_list(OptsList), is_atom(Mod), is_atom(Fun) -> + Opts = parse_opts(OptsList), + decoder({fun(E, S) -> Mod:Fun(E, S) end, State}, Opts); decoder(Callbacks, Opts) -> case Opts#opts.encoding of utf8 -> diff --git a/src/jsx_decoder.erl b/src/jsx_decoder.erl index 54ff537..ad27430 100644 --- a/src/jsx_decoder.erl +++ b/src/jsx_decoder.erl @@ -38,9 +38,9 @@ %% anyways, they are horrible and contrary to the spec. start(<>, Stack, Callbacks, Opts) -> - object(Rest, [key|Stack], callback(start_object, Callbacks), Opts); + object(Rest, [key|Stack], fold(start_object, Callbacks), Opts); start(<>, Stack, Callbacks, Opts) -> - array(Rest, [array|Stack], callback(start_array, Callbacks), Opts); + array(Rest, [array|Stack], fold(start_array, Callbacks), Opts); start(<>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true -> string(Rest, Stack, Callbacks, Opts, []); start(<<$t/utf8, Rest/binary>>, Stack, Callbacks, Opts) when Opts#opts.naked_values == true -> @@ -63,9 +63,9 @@ start(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> start(Stream, Stack, Callbacks, Opts) end. maybe_done(<>, [object|Stack], Callbacks, Opts) -> - maybe_done(Rest, Stack, callback(end_object, Callbacks), Opts); + maybe_done(Rest, Stack, fold(end_object, Callbacks), Opts); maybe_done(<>, [array|Stack], Callbacks, Opts) -> - maybe_done(Rest, Stack, callback(end_array, Callbacks), Opts); + maybe_done(Rest, Stack, fold(end_array, Callbacks), Opts); maybe_done(<>, [object|Stack], Callbacks, Opts) -> key(Rest, [key|Stack], Callbacks, Opts); maybe_done(<>, [array|_] = Stack, Callbacks, Opts) -> @@ -75,17 +75,17 @@ maybe_done(<>, Stack, Callbacks, Opts) when Opts#opt maybe_done(<>, Stack, Callbacks, Opts) when ?is_whitespace(S) -> maybe_done(Rest, Stack, Callbacks, Opts); maybe_done(<<>>, [], Callbacks, Opts) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {callback(eof, Callbacks), <<>>} + fun(<<>>) -> {fold(eof, Callbacks), <<>>} ;(Stream) -> maybe_done(Stream, [], Callbacks, Opts) end; maybe_done(<>, [], Callbacks, _Opts) -> - {callback(eof, Callbacks), Rest}; + {fold(eof, Callbacks), Rest}; maybe_done(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> maybe_done(Stream, Stack, Callbacks, Opts) end. object(<>, [key|Stack], Callbacks, Opts) -> - maybe_done(Rest, Stack, callback(end_object, Callbacks), Opts); + maybe_done(Rest, Stack, fold(end_object, Callbacks), Opts); object(<>, Stack, Callbacks, Opts) -> string(Rest, Stack, Callbacks, Opts, []); object(<>, Stack, Callbacks, Opts) when Opts#opts.comments == true -> @@ -99,11 +99,11 @@ object(<<>>, Stack, Callbacks, Opts) -> array(<>, Stack, Callbacks, Opts) -> string(Rest, Stack, Callbacks, Opts, []); array(<>, Stack, Callbacks, Opts) -> - object(Rest, [key|Stack], callback(start_object, Callbacks), Opts); + object(Rest, [key|Stack], fold(start_object, Callbacks), Opts); array(<>, Stack, Callbacks, Opts) -> - array(Rest, [array|Stack], callback(start_array, Callbacks), Opts); + array(Rest, [array|Stack], fold(start_array, Callbacks), Opts); array(<>, [array|Stack], Callbacks, Opts) -> - maybe_done(Rest, Stack, callback(end_array, Callbacks), Opts); + maybe_done(Rest, Stack, fold(end_array, Callbacks), Opts); array(<<$t/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> tr(Rest, Stack, Callbacks, Opts); array(<<$f/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> @@ -127,9 +127,9 @@ array(<<>>, Stack, Callbacks, Opts) -> value(<>, Stack, Callbacks, Opts) -> string(Rest, Stack, Callbacks, Opts, []); value(<>, Stack, Callbacks, Opts) -> - object(Rest, [key|Stack], callback(start_object, Callbacks), Opts); + object(Rest, [key|Stack], fold(start_object, Callbacks), Opts); value(<>, Stack, Callbacks, Opts) -> - array(Rest, [array|Stack], callback(start_array, Callbacks), Opts); + array(Rest, [array|Stack], fold(start_array, Callbacks), Opts); value(<<$t/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> tr(Rest, Stack, Callbacks, Opts); value(<<$f/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> @@ -176,9 +176,9 @@ key(<<>>, Stack, Callbacks, Opts) -> %% converted back to lists by the user anyways. string(<>, [key|_] = Stack, Callbacks, Opts, Acc) -> - colon(Rest, Stack, callback({key, lists:reverse(Acc)}, Callbacks), Opts); + colon(Rest, Stack, fold({key, lists:reverse(Acc)}, Callbacks), Opts); string(<>, Stack, Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback({string, lists:reverse(Acc)}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({string, lists:reverse(Acc)}, Callbacks), Opts); string(<>, Stack, Callbacks, Opts, Acc) -> escape(Rest, Stack, Callbacks, Opts, Acc); string(<>, Stack, Callbacks, Opts, Acc) when ?is_noncontrol(S) -> @@ -250,21 +250,21 @@ negative(<<>>, Stack, Callbacks, Opts, Acc) -> zero(<>, [object|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_object, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_object, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); zero(<>, [array|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_array, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_array, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); zero(<>, [object|Stack], Callbacks, Opts, Acc) -> - key(Rest, [key|Stack], callback({number, lists:reverse(Acc)}, Callbacks), Opts); + key(Rest, [key|Stack], fold({number, lists:reverse(Acc)}, Callbacks), Opts); zero(<>, [array|_] = Stack, Callbacks, Opts, Acc) -> - value(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + value(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); zero(<>, Stack, Callbacks, Opts, Acc) -> fraction(Rest, Stack, Callbacks, Opts, [?decimalpoint] ++ Acc); zero(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) -> - maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); zero(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> zero(Resume, Stack, Callbacks, Opts, Acc) end); zero(<>, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)), Rest} + fun(<<>>) -> {fold(eof, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} ;(Stream) -> zero(Stream, [], Callbacks, Opts, Acc) end; zero(<<>>, Stack, Callbacks, Opts, Acc) -> @@ -273,13 +273,13 @@ zero(<<>>, Stack, Callbacks, Opts, Acc) -> integer(<>, [object|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_object, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_object, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); integer(<>, [array|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_array, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_array, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); integer(<>, [object|Stack], Callbacks, Opts, Acc) -> - key(Rest, [key|Stack], callback({number, lists:reverse(Acc)}, Callbacks), Opts); + key(Rest, [key|Stack], fold({number, lists:reverse(Acc)}, Callbacks), Opts); integer(<>, [array|_] = Stack, Callbacks, Opts, Acc) -> - value(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + value(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); integer(<>, Stack, Callbacks, Opts, Acc) -> fraction(Rest, Stack, Callbacks, Opts, [?decimalpoint] ++ Acc); integer(<>, Stack, Callbacks, Opts, Acc) -> @@ -291,11 +291,11 @@ integer(<<"E"/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) -> integer(<>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S) -> integer(Rest, Stack, Callbacks, Opts, [S] ++ Acc); integer(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) -> - maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); integer(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> integer(Resume, Stack, Callbacks, Opts, Acc) end); integer(<<>> = Rest, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)), Rest} + fun(<<>>) -> {fold(eof, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} ;(Stream) -> integer(Stream, [], Callbacks, Opts, Acc) end; integer(<<>>, Stack, Callbacks, Opts, Acc) -> @@ -303,13 +303,13 @@ integer(<<>>, Stack, Callbacks, Opts, Acc) -> fraction(<>, [object|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_object, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_object, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); fraction(<>, [array|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_array, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_array, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); fraction(<>, [object|Stack], Callbacks, Opts, Acc) -> - key(Rest, [key|Stack], callback({number, lists:reverse(Acc)}, Callbacks), Opts); + key(Rest, [key|Stack], fold({number, lists:reverse(Acc)}, Callbacks), Opts); fraction(<>, [array|_] = Stack, Callbacks, Opts, Acc) -> - value(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + value(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); fraction(<>, Stack, Callbacks, Opts, Acc) -> fraction(Rest, Stack, Callbacks, Opts, [?zero] ++ Acc); fraction(<<"e"/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) -> @@ -319,11 +319,11 @@ fraction(<<"E"/utf8, Rest/binary>>, Stack, Callbacks, Opts, Acc) -> fraction(<>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S) -> fraction(Rest, Stack, Callbacks, Opts, [S] ++ Acc); fraction(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) -> - maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); fraction(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> fraction(Resume, Stack, Callbacks, Opts, Acc) end); fraction(<>, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)), Rest} + fun(<<>>) -> {fold(eof, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} ;(Stream) -> fraction(Stream, [], Callbacks, Opts, Acc) end; fraction(<<>>, Stack, Callbacks, Opts, Acc) -> @@ -345,23 +345,23 @@ ex(<<>>, Stack, Callbacks, Opts, Acc) -> exp(<>, [object|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_object, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_object, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); exp(<>, [array|Stack], Callbacks, Opts, Acc) -> - maybe_done(Rest, Stack, callback(end_array, callback({number, lists:reverse(Acc)}, Callbacks)), Opts); + maybe_done(Rest, Stack, fold(end_array, fold({number, lists:reverse(Acc)}, Callbacks)), Opts); exp(<>, [object|Stack], Callbacks, Opts, Acc) -> - key(Rest, [key|Stack], callback({number, lists:reverse(Acc)}, Callbacks), Opts); + key(Rest, [key|Stack], fold({number, lists:reverse(Acc)}, Callbacks), Opts); exp(<>, [array|_] = Stack, Callbacks, Opts, Acc) -> - value(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + value(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); exp(<>, Stack, Callbacks, Opts, Acc) -> exp(Rest, Stack, Callbacks, Opts, [?zero] ++ Acc); exp(<>, Stack, Callbacks, Opts, Acc) when ?is_nonzero(S) -> exp(Rest, Stack, Callbacks, Opts, [S] ++ Acc); exp(<>, Stack, Callbacks, Opts, Acc) when ?is_whitespace(S) -> - maybe_done(Rest, Stack, callback({number, lists:reverse(Acc)}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({number, lists:reverse(Acc)}, Callbacks), Opts); exp(<>, Stack, Callbacks, Opts, Acc) when Opts#opts.comments == true -> maybe_comment(Rest, fun(Resume) -> exp(Resume, Stack, Callbacks, Opts, Acc) end); exp(<>, [], Callbacks, Opts, Acc) when Opts#opts.explicit_termination == true -> - fun(<<>>) -> {callback(eof, callback({number, lists:reverse(Acc)}, Callbacks)), Rest} + fun(<<>>) -> {fold(eof, fold({number, lists:reverse(Acc)}, Callbacks)), Rest} ;(Stream) -> exp(Stream, [], Callbacks, Opts, Acc) end; exp(<<>>, Stack, Callbacks, Opts, Acc) -> @@ -381,7 +381,7 @@ tru(<<>>, Stack, Callbacks, Opts) -> true(<<"e"/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> - maybe_done(Rest, Stack, callback({literal, true}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({literal, true}, Callbacks), Opts); true(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> true(Stream, Stack, Callbacks, Opts) end. @@ -405,7 +405,7 @@ fals(<<>>, Stack, Callbacks, Opts) -> false(<<"e"/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> - maybe_done(Rest, Stack, callback({literal, false}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({literal, false}, Callbacks), Opts); false(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> false(Stream, Stack, Callbacks, Opts) end. @@ -423,7 +423,7 @@ nul(<<>>, Stack, Callbacks, Opts) -> null(<<"l"/utf8, Rest/binary>>, Stack, Callbacks, Opts) -> - maybe_done(Rest, Stack, callback({literal, null}, Callbacks), Opts); + maybe_done(Rest, Stack, fold({literal, null}, Callbacks), Opts); null(<<>>, Stack, Callbacks, Opts) -> fun(Stream) -> null(Stream, Stack, Callbacks, Opts) end. @@ -454,15 +454,12 @@ maybe_comment_done(<<>>, Resume) -> fun(Stream) -> maybe_comment_done(Stream, Resume) end. -%% helper function for dispatching of parser events +%% callbacks to our handler are roughly equivalent to a fold over the events, incremental +%% rather than all at once. -callback(eof, {{Mod, Function}, State}) -> - Mod:Function(eof, State); -callback(Event, {{Mod, Function}, State}) -> - {{Mod, Function}, Mod:Function(Event, State)}; -callback(eof, {F, State}) -> +fold(eof, {F, State}) -> F(eof, State); -callback(Event, {F, State}) when is_function(F) -> +fold(Event, {F, State}) when is_function(F) -> {F, F(Event, State)}.