From 7662c42ae756f048e00b150b4aa0d04f434fc24c Mon Sep 17 00:00:00 2001 From: Takeru Ohta Date: Sat, 11 Sep 2021 22:28:31 +0900 Subject: [PATCH] Add `jsone:term_to_json_string/1` as the default value of `map_unknown_value` option. --- src/jsone.erl | 14 +++++++++++--- src/jsone_encode.erl | 4 ++-- test/jsone_encode_tests.erl | 5 ++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/jsone.erl b/src/jsone.erl index 5d5fabd..fbc0100 100644 --- a/src/jsone.erl +++ b/src/jsone.erl @@ -33,7 +33,8 @@ decode/1, decode/2, try_decode/1, try_decode/2, encode/1, encode/2, - try_encode/1, try_encode/2 + try_encode/1, try_encode/2, + term_to_json_string/1 ]). -export_type([ @@ -196,7 +197,7 @@ | {object_key_type, string | scalar | value} | {space, non_neg_integer()} | {indent, non_neg_integer()} - | {map_unknown_value, fun ((term()) -> {ok, json_value()} | error)} + | {map_unknown_value, undefined | fun ((term()) -> {ok, json_value()} | error)} | skip_undefined | common_option(). %% `native_utf8':
@@ -236,7 +237,9 @@ %% - If speficied, each entry having `undefined' value in a object isn't included in the result JSON
%% %% `{map_unknown_value, Fun}`:
-%% - If specified, unknown values encountered during an encoding process are converted to `json_value()` by applying `Fun'. +%% - If `Fun' is a function, unknown values encountered during an encoding process are converted to `json_value()` by applying `Fun'.
+%% - If `Fun' is `undefined', the encoding results in an error if there are unknown values.
+%% - default: `term_to_json_string/1'
-type decode_option() :: {object_format, tuple | proplist | map} | {allow_ctrl_chars, boolean()} @@ -405,3 +408,8 @@ try_encode(JsonValue) -> -spec try_encode(json_value(), [encode_option()]) -> {ok, binary()} | {error, {Reason::term(), [stack_item()]}}. try_encode(JsonValue, Options) -> jsone_encode:encode(JsonValue, Options). + +%% @doc Converts the given term `X' to its string representation (i.e., the result of `io_lib:format("~p", [X])'). +-spec term_to_json_string(term()) -> {ok, json_string()} | error. +term_to_json_string(X) -> + {ok, list_to_binary(io_lib:format("~p", [X]))}. diff --git a/src/jsone_encode.erl b/src/jsone_encode.erl index 452b840..f661eda 100644 --- a/src/jsone_encode.erl +++ b/src/jsone_encode.erl @@ -72,7 +72,7 @@ indent = 0 :: non_neg_integer(), undefined_as_null = false :: boolean(), skip_undefined = false :: boolean(), - map_unknown_value = undefined :: undefined | fun ((term()) -> {ok, jsone:json_value()} | error) + map_unknown_value = fun jsone:term_to_json_string/1 :: undefined | fun ((term()) -> {ok, jsone:json_value()} | error) }). -define(OPT, #encode_opt_v2). -type opt() :: #encode_opt_v2{}. @@ -477,7 +477,7 @@ parse_option([undefined_as_null|T],Opt) -> parse_option(T, Opt?OPT{undefined_as_null = true}); parse_option([skip_undefined|T],Opt) -> parse_option(T, Opt?OPT{skip_undefined = true}); -parse_option([{map_unknown_value, F}|T], Opt) when is_function(F, 1) -> +parse_option([{map_unknown_value, F}|T], Opt) when is_function(F, 1); F =:= undefined -> parse_option(T, Opt?OPT{map_unknown_value = F}); parse_option(List, Opt) -> error(badarg, [List, Opt]). diff --git a/test/jsone_encode_tests.erl b/test/jsone_encode_tests.erl index d709eca..b817d2a 100644 --- a/test/jsone_encode_tests.erl +++ b/test/jsone_encode_tests.erl @@ -329,7 +329,10 @@ encode_test_() -> end}, {"invalid value", fun () -> - ?assertMatch({error, {badarg, _}}, jsone_encode:encode(self())) + Pid = self(), + PidString = list_to_binary(io_lib:format("~p", [Pid])), + ?assertEqual({ok, <<$", PidString/binary, $">>}, jsone_encode:encode(Pid)), + ?assertMatch({error, {badarg, _}}, jsone_encode:encode(Pid, [{map_unknown_value, undefined}])) end}, {"wrong option", fun () ->