Skip to content

Commit

Permalink
(feat) Erlang date() and datetime() encoders
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardb authored and lpil committed Oct 11, 2023
1 parent 076da3f commit 3725a7b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/thoas.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@
list(json_term()) |
#{ binary() => json_term() }.

-type input_term() ::
-type input_term() ::
integer() |
float() |
binary() |
atom() |
calendar:date_time() |
calendar:date() |
list(input_term()) |
list({binary() | atom(), input_term()}) |
#{ binary() | atom() => input_term() }.
Expand Down
27 changes: 26 additions & 1 deletion src/thoas_encode.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,32 @@ value(Value, _Escape) when is_float(Value) ->
float(Value);
value([{_, _} | _] = Keyword, Escape) ->
map_naive(Keyword, Escape);
value({Y, M, D}, Escape)
when is_integer(Y) andalso Y >= 0 andalso Y =< 9999 andalso
is_integer(M) andalso M >= 1 andalso M =< 12 andalso
is_integer(D) andalso D >= 1 andalso D =< 31 ->
DateTime = io_lib:format("~4..0b-~2..0b-~2..0b", [Y, M, D]),
encode_string(iolist_to_binary(DateTime), Escape);
value({{Y, M, D}, {H, I, S}}, Escape)
when is_integer(Y) andalso Y >= 0 andalso Y =< 9999 andalso
is_integer(M) andalso M >= 1 andalso M =< 12 andalso
is_integer(D) andalso D >= 1 andalso D =< 31 andalso
is_integer(H) andalso H >= 0 andalso H =< 23 andalso
is_integer(I) andalso I >= 0 andalso I =< 59 andalso
is_integer(S) andalso S >= 0 andalso S =< 59 ->
Dt = io_lib:format("~4..0b-~2..0b-~2..0bT~2..0b:~2..0b:~sZ",
[Y, M, D, H, I, integer_to_list(S)]),
encode_string(iolist_to_binary(Dt), Escape);
value({{Y, M, D}, {H, I, S}}, Escape)
when is_integer(Y) andalso Y >= 0 andalso Y =< 9999 andalso
is_integer(M) andalso M >= 1 andalso M =< 12 andalso
is_integer(D) andalso D >= 1 andalso D =< 31 andalso
is_integer(H) andalso H >= 0 andalso H =< 23 andalso
is_integer(I) andalso I >= 0 andalso I =< 59 andalso
is_float(S) andalso S >= 0 andalso S < 60 ->
Dt = io_lib:format("~4..0b-~2..0b-~2..0bT~2..0b:~2..0b:~sZ",
[Y, M, D, H, I, float_to_binary(S, [short])]),
encode_string(iolist_to_binary(Dt), Escape);
value(Value, Escape) when is_list(Value) ->
list(Value, Escape);
value(Value, Escape) when is_map(Value) ->
Expand All @@ -1736,4 +1762,3 @@ value(Value, Escape) when is_map(Value) ->
Keyword ->
map_naive(Keyword, Escape)
end.

11 changes: 11 additions & 0 deletions test/thoas_encode_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,14 @@ encode_test_() ->
?_assertEqual(Expected, iolist_to_binary(encode(Input, #{})))
|| {Input, Expected} <- Cases
].

types_test_() ->
Cases =[
{#{<<"date">> => {2023,8,7}}, <<"{\"date\":\"2023-08-07\"}">>},
{#{<<"datetime">> => {{2023,8,7},{19,2,24}}}, <<"{\"datetime\":\"2023-08-07T19:02:24Z\"}">>},
{#{<<"datetime">> => {{2023,8,7},{19,2,24.65432}}}, <<"{\"datetime\":\"2023-08-07T19:02:24.65432Z\"}">>}
],
[
?_assertEqual(Expected, iolist_to_binary(encode(Input, #{})))
|| {Input, Expected} <- Cases
].

0 comments on commit 3725a7b

Please sign in to comment.