Browse Source

Add `jsone:term_to_json_string/1` as the default value of `map_unknown_value` option.

Takeru Ohta 3 years ago
parent
commit
7662c42ae7
3 changed files with 17 additions and 6 deletions
  1. 11 3
      src/jsone.erl
  2. 2 2
      src/jsone_encode.erl
  3. 4 1
      test/jsone_encode_tests.erl

+ 11 - 3
src/jsone.erl

@@ -33,7 +33,8 @@
          decode/1, decode/2,
          decode/1, decode/2,
          try_decode/1, try_decode/2,
          try_decode/1, try_decode/2,
          encode/1, encode/2,
          encode/1, encode/2,
-         try_encode/1, try_encode/2
+         try_encode/1, try_encode/2,
+         term_to_json_string/1
         ]).
         ]).
 
 
 -export_type([
 -export_type([
@@ -196,7 +197,7 @@
                        | {object_key_type, string | scalar | value}
                        | {object_key_type, string | scalar | value}
                        | {space, non_neg_integer()}
                        | {space, non_neg_integer()}
                        | {indent, 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
                        | skip_undefined
                        | common_option().
                        | common_option().
 %% `native_utf8': <br />
 %% `native_utf8': <br />
@@ -236,7 +237,9 @@
 %% - If speficied, each entry having `undefined' value in a object isn't included in the result JSON <br />
 %% - If speficied, each entry having `undefined' value in a object isn't included in the result JSON <br />
 %%
 %%
 %% `{map_unknown_value, Fun}`: <br />
 %% `{map_unknown_value, Fun}`: <br />
-%% - 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'. <br />
+%% - If `Fun' is `undefined', the encoding results in an error if there are unknown values. <br />
+%% - default: `term_to_json_string/1' <br />
 
 
 -type decode_option() :: {object_format, tuple | proplist | map}
 -type decode_option() :: {object_format, tuple | proplist | map}
                        | {allow_ctrl_chars, boolean()}
                        | {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()]}}.
 -spec try_encode(json_value(), [encode_option()]) -> {ok, binary()} | {error, {Reason::term(), [stack_item()]}}.
 try_encode(JsonValue, Options) ->
 try_encode(JsonValue, Options) ->
     jsone_encode: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]))}.

+ 2 - 2
src/jsone_encode.erl

@@ -72,7 +72,7 @@
           indent = 0 :: non_neg_integer(),
           indent = 0 :: non_neg_integer(),
           undefined_as_null = false :: boolean(),
           undefined_as_null = false :: boolean(),
           skip_undefined = 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).
 -define(OPT, #encode_opt_v2).
 -type 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(T, Opt?OPT{undefined_as_null = true});
 parse_option([skip_undefined|T],Opt) ->
 parse_option([skip_undefined|T],Opt) ->
     parse_option(T, Opt?OPT{skip_undefined = true});
     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(T, Opt?OPT{map_unknown_value = F});
 parse_option(List, Opt) ->
 parse_option(List, Opt) ->
     error(badarg, [List, Opt]).
     error(badarg, [List, Opt]).

+ 4 - 1
test/jsone_encode_tests.erl

@@ -329,7 +329,10 @@ encode_test_() ->
       end},
       end},
      {"invalid value",
      {"invalid value",
       fun () ->
       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},
       end},
      {"wrong option",
      {"wrong option",
       fun () ->
       fun () ->