Browse Source

Fix json_term clash with proplist object representation

This example shows the difference:

<<"{\"json\":\"[1,2,3]\"}">> = jsone:encode([{json, <<"[1,2,3]">>}]).
<<"[[1,2,3]]">> = jsone:encode([{{json, <<"[1,2,3]">>}}]).
Hynek Vychodil 8 years ago
parent
commit
83729f6aff
5 changed files with 30 additions and 24 deletions
  1. 2 2
      README.md
  2. 8 8
      doc/jsone.md
  3. 8 8
      src/jsone.erl
  4. 2 2
      src/jsone_encode.erl
  5. 10 4
      test/jsone_encode_tests.erl

+ 2 - 2
README.md

@@ -187,8 +187,8 @@ abc                    -> "abc"                      -> <<"abc">> % non-special
 [{<<"key">>, val}]     -> {"key":"val"}              -> [{<<"key">>, <<"val">>}]   % object_format=proplist
 #{}                    -> {}                         -> #{}                        % object_format=map
 #{key => val}          -> {"key":"val"}              -> #{<<"key">> => <<"val">>}  % object_format=map
-{json, IOList}         -> Value                      -> ~~~                        % UTF-8 encoded term**
-{json_utf8, Chars}     -> Value                      -> ~~~                        % Unicode code points**
+{{json, IOList}}       -> Value                      -> ~~~                        % UTF-8 encoded term**
+{{json_utf8, Chars}}   -> Value                      -> ~~~                        % Unicode code points**
 ```
 
 \* see [jsone:datetime_encode_format()](doc/jsone.md#type-datetime_encode_format)

+ 8 - 8
doc/jsone.md

@@ -260,7 +260,7 @@ NOTE: `decode/1` always returns `binary()` value
 
 
 <pre><code>
-json_term() = {json, iolist()} | {json_utf8, <a href="unicode.md#type-chardata">unicode:chardata()</a>}
+json_term() = {{json, iolist()}} | {{json_utf8, <a href="unicode.md#type-chardata">unicode:chardata()</a>}}
 </code></pre>
 
 `json_term()` allows inline already encoded JSON value. `json` variant
@@ -279,13 +279,13 @@ A simple example is worth a thousand words.
   true
   3> S.
   [104,233,108,111]
-  4> B = jsone:encode({json, S}).  % invalid UTF-8
+  4> B = jsone:encode({{json, S}}).  % invalid UTF-8
   <<104,233,108,111>>
-  5> B2 = jsone:encode({json_utf8, S}). % valid UTF-8
+  5> B2 = jsone:encode({{json_utf8, S}}). % valid UTF-8
   <<104,195,169,108,111>>
-  6> jsone:encode({json, B}).
+  6> jsone:encode({{json, B}}).
   <<104,233,108,111>>
-  7> jsone:encode({json_utf8, B}).
+  7> jsone:encode({{json_utf8, B}}).
   ** exception error: {invalid_json_utf8,<<104>>,<<233,108,111>>}
        in function  jsone_encode:value/4
           called as jsone_encode:value({json_utf8,<<104,233,108,111>>},
@@ -295,13 +295,13 @@ A simple example is worth a thousand words.
                                                       {iso8601,0},
                                                       string,0,0})
        in call from jsone:encode/2 (/home/hynek/work/altworx/jsone/_build/default/lib/jsone/src/jsone.erl, line 302)
-  8> jsone:encode({json_utf8, B2}).
+  8> jsone:encode({{json_utf8, B2}}).
   <<104,195,169,108,111>>
   9> shell:strings(true).
   false
-  10> jsone:encode({json_utf8, B2}).
+  10> jsone:encode({{json_utf8, B2}}).
   <<"hélo"/utf8>>
-  11> jsone:encode({json, binary_to_list(B2)}). % UTF-8 encoded list leads to valid UTF-8
+  11> jsone:encode({{json, binary_to_list(B2)}}). % UTF-8 encoded list leads to valid UTF-8
   <<"hélo"/utf8>>
 ```
 

+ 8 - 8
src/jsone.erl

@@ -69,7 +69,7 @@
                              | json_object_format_proplist()
                              | json_object_format_map().
 -type json_object_members() :: [{json_string(), json_value()}].
--type json_term()           :: {json, iolist()} | {json_utf8, unicode:chardata()}.
+-type json_term()           :: {{json, iolist()}} | {{json_utf8, unicode:chardata()}}.
 %% `json_term()' allows inline already encoded JSON value. `json' variant
 %% expects byte encoded utf8 data values as list members. `json_utf8' expect
 %% Unicode code points as list members. Binaries are copied "as is" in both
@@ -86,13 +86,13 @@
 %% true
 %% 3> S.
 %% [104,233,108,111]
-%% 4> B = jsone:encode({json, S}).  % invalid UTF-8
+%% 4> B = jsone:encode({{json, S}}).  % invalid UTF-8
 %% <<104,233,108,111>>
-%% 5> B2 = jsone:encode({json_utf8, S}). % valid UTF-8
+%% 5> B2 = jsone:encode({{json_utf8, S}}). % valid UTF-8
 %% <<104,195,169,108,111>>
-%% 6> jsone:encode({json, B}).
+%% 6> jsone:encode({{json, B}}).
 %% <<104,233,108,111>>
-%% 7> jsone:encode({json_utf8, B}).
+%% 7> jsone:encode({{json_utf8, B}}).
 %% ** exception error: {invalid_json_utf8,<<104>>,<<233,108,111>>}
 %%      in function  jsone_encode:value/4
 %%         called as jsone_encode:value({json_utf8,<<104,233,108,111>>},
@@ -102,13 +102,13 @@
 %%                                                     {iso8601,0},
 %%                                                     string,0,0})
 %%      in call from jsone:encode/2 (/home/hynek/work/altworx/jsone/_build/default/lib/jsone/src/jsone.erl, line 302)
-%% 8> jsone:encode({json_utf8, B2}).
+%% 8> jsone:encode({{json_utf8, B2}}).
 %% <<104,195,169,108,111>>
 %% 9> shell:strings(true).
 %% false
-%% 10> jsone:encode({json_utf8, B2}).
+%% 10> jsone:encode({{json_utf8, B2}}).
 %% <<"hélo"/utf8>>
-%% 11> jsone:encode({json, binary_to_list(B2)}). % UTF-8 encoded list leads to valid UTF-8
+%% 11> jsone:encode({{json, binary_to_list(B2)}}). % UTF-8 encoded list leads to valid UTF-8
 %% <<"hélo"/utf8>>
 %% '''
 %%

+ 2 - 2
src/jsone_encode.erl

@@ -111,14 +111,14 @@ next(Level = [Next | Nexts], Buf, Opt) ->
 value(null, Nexts, Buf, Opt)                         -> next(Nexts, <<Buf/binary, "null">>, Opt);
 value(false, Nexts, Buf, Opt)                        -> next(Nexts, <<Buf/binary, "false">>, Opt);
 value(true, Nexts, Buf, Opt)                         -> next(Nexts, <<Buf/binary, "true">>, Opt);
-value({json, T}, Nexts, Buf, Opt) ->
+value({{json, T}}, Nexts, Buf, Opt) ->
     try
         next(Nexts, <<Buf/binary, (iolist_to_binary(T))/binary>>, Opt)
     catch
          error:badarg ->
             ?ERROR(value, [{json, T}, Nexts, Buf, Opt])
     end;
-value({json_utf8, T}, Nexts, Buf, Opt) ->
+value({{json_utf8, T}}, Nexts, Buf, Opt) ->
     try unicode:characters_to_binary(T) of
         {error, OK, Invalid} ->
             {error, {{invalid_json_utf8, OK, Invalid}, [{?MODULE, value, [{json_utf8, T}, Nexts, Buf, Opt], [{line, ?LINE}]}]}};

+ 10 - 4
test/jsone_encode_tests.erl

@@ -36,13 +36,19 @@ encode_test_() ->
               ?assertEqual(
                  {ok, <<"{\"foo\":[1,2,3],\"bar\":\"",195,169,"ok\"}">>},
                  jsone_encode:encode(
-                   ?OBJ2(foo, {json, ["["|[$1, ",2",<<",3]">>]]},
-                         <<"bar">>, {json_utf8, [$", 233, "ok", $"]}))),
+                   ?OBJ2(foo, {{json, ["["|[$1, ",2",<<",3]">>]]}},
+                         <<"bar">>, {{json_utf8, [$", 233, "ok", $"]}}))),
               ?assertEqual(
                  {ok, <<"{\"foo\":[1,2,3],\"bar\":\"",233,"ok\"}">>},
                  jsone_encode:encode(
-                   ?OBJ2(foo, {json, ["["|[$1, ",2",<<",3]">>]]},
-                         <<"bar">>, {json, [$", 233, "ok", $"]})))
+                   ?OBJ2(foo, {{json, ["["|[$1, ",2",<<",3]">>]]}},
+                         <<"bar">>, {{json, [$", 233, "ok", $"]}}))),
+              ?assertEqual(
+                 {ok, <<"{\"json\":\"[1,2,3]\"}">>},
+                 jsone_encode:encode([{json, <<"[1,2,3]">>}])),
+              ?assertEqual(
+                 {ok, <<"[[1,2,3]]">>},
+                 jsone_encode:encode([{{json, <<"[1,2,3]">>}}]))
       end},
      %% Numbers: Integer
      {"zero",