minor api change and refactoring of pretty_printer.erl

This commit is contained in:
alisdair sullivan 2010-05-25 13:31:41 -07:00
parent 6662a1ee98
commit 5d014bbef8
6 changed files with 58 additions and 43 deletions

View file

@ -6,10 +6,14 @@
indent = 4 indent = 4
}). }).
print(JSON, Opts) -> print(JSON, Opts) ->
Init = init(parse_opts(Opts, #opts{})), Init = init(parse_opts(Opts, #opts{})),
{{pretty_printer, Result}, _} = (jsx:decoder({pretty_printer, Init}, []))(JSON), {{_, Result}, Rest} = (jsx:decoder({{pretty_printer, jsx_event}, Init}, []))(JSON),
Result. case jsx:tail_clean(Rest) of
true -> Result
; _ -> exit(badarg)
end.
parse_opts([{indent, Val}|Rest], Opts) -> parse_opts([{indent, Val}|Rest], Opts) ->
parse_opts(Rest, Opts#opts{indent = Val}); parse_opts(Rest, Opts#opts{indent = Val});
@ -17,48 +21,58 @@ parse_opts([], Opts) ->
Opts. Opts.
init(Opts) -> init(Opts) ->
{[], Opts#opts.indent, 0, false}. {[], Opts#opts.indent, 0, new}.
jsx_event(start_object, {Acc, Indent, Level, value}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ "{", Indent, Level + 1, new};
jsx_event(start_object, {Acc, Indent, Level, _}) -> jsx_event(start_object, {Acc, Indent, Level, _}) ->
{Acc ++ "{", Indent, Level + 1, false}; {Acc ++ "{", Indent, Level + 1, new};
jsx_event(start_array, {Acc, Indent, Level, value}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ "[", Indent, Level + 1, new};
jsx_event(start_array, {Acc, Indent, Level, _}) -> jsx_event(start_array, {Acc, Indent, Level, _}) ->
{Acc ++ "[", Indent, Level + 1, false}; {Acc ++ "[", Indent, Level + 1, new};
jsx_event({key, Key}, {Acc, Indent, Level, true}) ->
{Acc ++ ",\n" ++ indent(Indent, Level) ++ "\"" ++ Key ++ "\": ", Indent, Level, false};
jsx_event({key, Key}, {Acc, Indent, Level, false}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ "\"" ++ Key ++ "\": ", Indent, Level, false};
jsx_event({number, Number}, {Acc, Indent, Level, true}) -> jsx_event(end_object, {Acc, Indent, Level, value}) ->
{Acc ++ ",\n" ++ indent(Indent, Level) ++ Number, Indent, Level, true}; {Acc ++ "\n" ++ indent(Indent, Level - 1) ++ "}", Indent, Level - 1, value};
jsx_event({number, Number}, {Acc, Indent, Level, false}) -> jsx_event(end_object, {Acc, Indent, Level, new}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ Number, Indent, Level, true}; {Acc ++ "}", Indent, Level - 1, value};
jsx_event({string, String}, {Acc, Indent, Level, true}) ->
{Acc ++ ",\n" ++ indent(Indent, Level) ++ "\"" ++ String ++ "\"", Indent, Level, true};
jsx_event({string, String}, {Acc, Indent, Level, false}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ "\"" ++ String ++ "\"", Indent, Level, true};
jsx_event({literal, Literal}, {Acc, Indent, Level, true}) -> jsx_event(end_array, {Acc, Indent, Level, value}) ->
{Acc ++ ",\n" ++ indent(Indent, Level) ++ atom_to_list(Literal), Indent, Level, true}; {Acc ++ "\n" ++ indent(Indent, Level - 1) ++ "]", Indent, Level - 1, value};
jsx_event({literal, Literal}, {Acc, Indent, Level, false}) -> jsx_event(end_array, {Acc, Indent, Level, new}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ atom_to_list(Literal), Indent, Level, true}; {Acc ++ "]", Indent, Level - 1, value};
jsx_event({key, Key}, {Acc, Indent, Level, value}) ->
{Acc ++ ",\n" ++ indent(Indent, Level) ++ "\"" ++ Key ++ "\": ", Indent, Level, key};
jsx_event({key, Key}, {Acc, Indent, Level, _}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ "\"" ++ Key ++ "\": ", Indent, Level, key};
jsx_event({Type, Value}, {Acc, Indent, Level, value}) ->
{Acc ++ ",\n" ++ indent(Indent, Level) ++ format(Type, Value), Indent, Level, value};
jsx_event({Type, Value}, {Acc, Indent, Level, new}) ->
{Acc ++ "\n" ++ indent(Indent, Level) ++ format(Type, Value), Indent, Level, value};
jsx_event({Type, Value}, {Acc, Indent, Level, key}) ->
{Acc ++ format(Type, Value), Indent, Level, value};
jsx_event(end_object, {Acc, Indent, Level, true}) ->
{Acc ++ "\n" ++ indent(Indent, Level - 1) ++ "}", Indent, Level - 1, true};
jsx_event(end_object, {Acc, Indent, Level, false}) ->
{Acc ++ "}", Indent, Level - 1, true};
jsx_event(end_array, {Acc, Indent, Level, true}) ->
{Acc ++ "\n" ++ indent(Indent, Level - 1) ++ "]", Indent, Level - 1, true};
jsx_event(end_array, {Acc, Indent, Level, false}) ->
{Acc ++ "]", Indent, Level - 1, true};
jsx_event(eof, {Acc, _, _, _}) -> jsx_event(eof, {Acc, _, _, _}) ->
Acc. Acc.
format(number, Number) ->
Number;
format(string, String) ->
"\"" ++ String ++ "\"";
format(literal, Literal) ->
erlang:atom_to_list(Literal).
indent(Indent, Level) -> indent(Indent, Level) ->
[ 16#20 || _ <- lists:seq(1, Indent * Level) ]. [ 16#20 || _ <- lists:seq(1, Indent * Level) ].

View file

@ -1,11 +1,9 @@
-module(jsx). -module(jsx).
-export([decoder/0, decoder/2, decode/3]). -export([decoder/0, decoder/2, tail_clean/1]).
-include("jsx_common.hrl"). -include("jsx_common.hrl").
decode(JSON, Callbacks, Opts) ->
(decoder(Callbacks, Opts))(JSON).
decoder() -> decoder() ->
decoder(none, []). decoder(none, []).
@ -43,8 +41,14 @@ parse_opts([{explicit_termination, Value}|Rest], Opts) ->
init_callbacks(none) -> init_callbacks(none) ->
{none, []}; {none, []};
init_callbacks({M, S}) when is_atom(M) -> init_callbacks({{M, F}, S}) when is_atom(M), is_atom(F) ->
{M, S}; {{M, F}, S};
init_callbacks({F, S}) when is_function(F) -> init_callbacks({F, S}) when is_function(F) ->
{F, S}. {F, S}.
tail_clean(<<X/utf8, Rest/binary>>) when ?is_whitespace(X) ->
tail_clean(Rest);
tail_clean(<<>>) ->
true;
tail_clean(_) ->
false.

View file

@ -433,8 +433,8 @@ callback(eof, {none, Callbacks}) ->
lists:reverse(Callbacks); lists:reverse(Callbacks);
callback(Event, {none, Callbacks}) -> callback(Event, {none, Callbacks}) ->
{none, [Event] ++ Callbacks}; {none, [Event] ++ Callbacks};
callback(Event, {Mod, State}) when is_atom(Mod) -> callback(Event, {{Mod, Function}, State}) when is_atom(Mod) ->
{Mod, Mod:jsx_event(Event, State)}; {{Mod, Function}, Mod:Function(Event, State)};
callback(Event, {F, State}) when is_function(F) -> callback(Event, {F, State}) when is_function(F) ->
{F, F(Event, State)}. {F, F(Event, State)}.

View file

@ -1 +0,0 @@
[ "arabic letter alef: ", "\u0627" ]

View file

@ -1,2 +0,0 @@
[start_array, {string, "arabic letter alef: "}, {string, [16#0627]}, end_array].
[{escaped_unicode, codepoint}].

View file

@ -7,7 +7,7 @@
test(Dir) -> test(Dir) ->
Tests = gen_tests(Dir), Tests = gen_tests(Dir),
eunit:test(Tests). eunit:test(Tests, [verbose]).
gen_tests(Dir) -> gen_tests(Dir) ->
TestSpecs = filelib:wildcard("*.test", Dir), TestSpecs = filelib:wildcard("*.test", Dir),