Skip to content

Commit

Permalink
Split code into functions
Browse files Browse the repository at this point in the history
  • Loading branch information
williamthome committed Nov 7, 2023
1 parent 051cff7 commit f0ac8ae
Showing 1 changed file with 51 additions and 50 deletions.
101 changes: 51 additions & 50 deletions src/jsxrecord.erl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
]).

-define(RECORD_TYPE, <<"_type">>).
-define(IS_PROPLIST_KEY(X), is_binary(X) orelse is_atom(X) orelse is_integer(X)).

-include_lib("kernel/include/logger.hrl").

Expand Down Expand Up @@ -91,31 +92,8 @@ do_load_records(Modules, CurrRecordDefs) ->
encode_json(Term) ->
Options = #{
nulls => [undefined, null],
list_encoder => fun
([{K, _} | _] = Proplist, Opts)
when is_binary(K); is_atom(K); is_integer(K) ->
Map = proplists:to_map(Proplist),
euneus_encoder:encode_map(Map, Opts);
(List, Opts) ->
euneus_encoder:encode_list(List, Opts)
end,
unhandled_encoder => fun
({struct, MochiJSON}, Opts) ->
Map = mochijson_to_map(MochiJSON),
euneus_encoder:encode_map(Map, Opts);
(R, _Opts) when is_tuple(R), is_atom(element(1, R)) ->
T = atom_to_binary(element(1, R), utf8),
case maps:find(T, record_defs()) of
{ok, Def} ->
encode_json(expand_record_1(
Def, 2, R, #{ ?RECORD_TYPE => T }
));
error ->
euneus_encoder:throw_unsupported_type_error(R)
end;
(T, _Opts) ->
euneus_encoder:throw_unsupported_type_error(T)
end,
list_encoder => fun encode_list/2,
unhandled_encoder => fun encode_tuple/2,
error_handler => fun jsx_error/3
},
case euneus:encode_to_binary(Term, Options) of
Expand All @@ -128,31 +106,7 @@ encode_json(Term) ->
decode_json(<<>>) -> undefined;
decode_json(B) ->
Options = #{
objects => fun(M1, _Opts) ->
case maps:find(?RECORD_TYPE, M1) of
{ok, Type} ->
case maps:find(Type, record_defs_int()) of
{ok, Def} ->
Rec = lists:foldl(
fun({F, Default}, Acc) ->
V1 = case maps:get(F, M1, Default) of
V when is_map(V), is_list(Default) ->
make_proplist(V);
V ->
V
end,
[ V1 | Acc ]
end,
[ binary_to_atom(Type, utf8) ],
Def),
list_to_tuple( lists:reverse(Rec) );
error ->
M1
end;
error ->
M1
end
end
objects => fun reconstitute_records/2
},
case euneus:decode(B, Options) of
{ok, Term} ->
Expand All @@ -161,6 +115,28 @@ decode_json(B) ->
error(Reason)
end.

encode_list([{K, _} | _] = Proplist, Opts) when ?IS_PROPLIST_KEY(K) ->
Map = proplists:to_map(Proplist),
euneus_encoder:encode_map(Map, Opts);
encode_list(List, Opts) ->
euneus_encoder:encode_list(List, Opts).

encode_tuple({struct, MochiJSON}, Opts) ->
Map = mochijson_to_map(MochiJSON),
euneus_encoder:encode_map(Map, Opts);
encode_tuple(R, _Opts) when is_tuple(R), is_atom(element(1, R)) ->
T = atom_to_binary(element(1, R), utf8),
case maps:find(T, record_defs()) of
{ok, Def} ->
encode_json(expand_record_1(
Def, 2, R, #{ ?RECORD_TYPE => T }
));
error ->
euneus_encoder:throw_unsupported_type_error(R)
end;
encode_tuple(T, _Opts) ->
euneus_encoder:throw_unsupported_type_error(T).

jsx_error(throw, {{token, Token}, Rest, Opts, Input, Pos, Buffer}, _Stacktrace) ->
?LOG_ERROR(#{
in => jsxrecord,
Expand All @@ -174,6 +150,31 @@ jsx_error(throw, {{token, Token}, Rest, Opts, Input, Pos, Buffer}, _Stacktrace)
jsx_error(Class, Reason, Stacktrace) ->
euneus_decoder:handle_error(Class, Reason, Stacktrace).

reconstitute_records(M1, _Opts) ->
case maps:find(?RECORD_TYPE, M1) of
{ok, Type} ->
case maps:find(Type, record_defs_int()) of
{ok, Def} ->
Rec = lists:foldl(
fun({F, Default}, Acc) ->
V1 = case maps:get(F, M1, Default) of
V when is_map(V), is_list(Default) ->
make_proplist(V);
V ->
V
end,
[ V1 | Acc ]
end,
[ binary_to_atom(Type, utf8) ],
Def),
list_to_tuple( lists:reverse(Rec) );
error ->
M1
end;
error ->
M1
end.

make_proplist(Map) ->
L = maps:to_list(Map),
lists:map(
Expand Down

0 comments on commit f0ac8ae

Please sign in to comment.