Browse Source

Refactoring

Takeru Ohta 10 years ago
parent
commit
0eb585b475
7 changed files with 114 additions and 68 deletions
  1. 1 1
      COPYING
  2. 19 10
      README.md
  3. 32 2
      doc/jsone.md
  4. 18 14
      src/jsone.erl
  5. 11 8
      src/jsone_decode.erl
  6. 30 30
      src/jsone_encode.erl
  7. 3 3
      test/jsone_decode_tests.erl

+ 1 - 1
COPYING

@@ -1,6 +1,6 @@
 The MIT License
 The MIT License
 
 
-Copyright (c) 2013-2014 Takeru Ohta <phjgt308@gmail.com>
+Copyright (c) 2013-2015 Takeru Ohta <phjgt308@gmail.com>
 
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 of this software and associated documentation files (the "Software"), to deal

+ 19 - 10
README.md

@@ -1,4 +1,4 @@
-jsone (0.2.4)
+jsone (0.3.0)
 =============
 =============
 
 
 An Erlang library for encoding, decoding [JSON](http://json.org/index.html) data.
 An Erlang library for encoding, decoding [JSON](http://json.org/index.html) data.
@@ -101,18 +101,27 @@ Usage Example
 Data Mapping (Erlang <=> JSON)
 Data Mapping (Erlang <=> JSON)
 -------------------------------
 -------------------------------
 
 
-|         | Erlang                                 | JSON                       |
-|:-------:|---------------------------------------:|---------------------------:|
-| number  |                                    123 |                        123 |
-| null    |                                   null |                       null |
-| boolean |                                   true |                       true |
-| string  |                              <<"abc">> |                      "abc" |
-| array   |                                [1,2,3] |                    [1,2,3] |
-| object  | {[{<<"key">>,<<"value">>},{hoge,123}]} | {"key":"value","hoge":123} |
-
+```
+Erlang                  JSON             Erlang
+=================================================================================================
+
+null                 -> null          -> null
+true                 -> true          -> true
+false                -> false         -> false
+<<"abc">>            -> "abc"         -> <<"abc">>
+abc                  -> "abc"         -> <<"abc">> % non-special atom is regarded as a binary
+123                  -> 123           -> 123
+123.4                -> 123.4         -> 123.4
+[1,2,3]              -> [1,2,3]       -> [1,2,3]
+{[]}                 -> {}            -> {[]}                       % object_format=tuple
+{[{key, <<"val">>}]} -> {"key":"val"} -> {[{<<"key">>, <<"val">>}]} % object_format=tuple
+[{}]                 -> {}            -> [{}]                       % object_format=proplist
+[{<<"key">>, val}]   -> {"key":"val"} -> [{<<"key">>, <<"val">>}]   % object_format=proplist
+```
 
 
 API
 API
 ---
 ---
+
 See [EDoc Document](doc/jsone.md)
 See [EDoc Document](doc/jsone.md)
 
 
 
 

+ 32 - 2
doc/jsone.md

@@ -22,11 +22,17 @@ JSON decoding/encoding module.
 
 
 
 
 <pre><code>
 <pre><code>
-decode_option() = {format, eep18 | proplist}
+decode_option() = {object_format, tuple | proplist}
 </code></pre>
 </code></pre>
 
 
 
 
 
 
+  object_format: <br />
+- Decoded JSON object format <br />
+- `tuple`: An object is decoded as `{[]}` if it is empty, otherwise `{[{Key, Value}]}`. <br />
+- `proplist`: An object is decoded as `[{}]` if it is empty, otherwise `[{Key, Value}]`. <br />
+- default: `tuple` <br />
+
 
 
 
 
 ### <a name="type-encode_option">encode_option()</a> ###
 ### <a name="type-encode_option">encode_option()</a> ###
@@ -84,7 +90,31 @@ json_number() = number()
 
 
 
 
 <pre><code>
 <pre><code>
-json_object() = {<a href="#type-json_object_members">json_object_members()</a>} | [{}] | <a href="#type-json_object_members">json_object_members()</a>
+json_object() = <a href="#type-json_object_format_tuple">json_object_format_tuple()</a> | <a href="#type-json_object_format_proplist">json_object_format_proplist()</a>
+</code></pre>
+
+
+
+
+
+### <a name="type-json_object_format_proplist">json_object_format_proplist()</a> ###
+
+
+
+<pre><code>
+json_object_format_proplist() = [{}] | <a href="#type-json_object_members">json_object_members()</a>
+</code></pre>
+
+
+
+
+
+### <a name="type-json_object_format_tuple">json_object_format_tuple()</a> ###
+
+
+
+<pre><code>
+json_object_format_tuple() = {<a href="#type-json_object_members">json_object_members()</a>}
 </code></pre>
 </code></pre>
 
 
 
 

+ 18 - 14
src/jsone.erl

@@ -1,7 +1,7 @@
 %%% @doc JSON decoding/encoding module
 %%% @doc JSON decoding/encoding module
 %%% @end
 %%% @end
 %%%
 %%%
-%%% Copyright (c) 2013-2014, Takeru Ohta <phjgt308@gmail.com>
+%%% Copyright (c) 2013-2015, Takeru Ohta <phjgt308@gmail.com>
 %%%
 %%%
 %%% The MIT License
 %%% The MIT License
 %%%
 %%%
@@ -38,12 +38,14 @@
 
 
 -export_type([
 -export_type([
               json_value/0,
               json_value/0,
+              json_boolean/0,
               json_number/0,
               json_number/0,
               json_string/0,
               json_string/0,
               json_array/0,
               json_array/0,
               json_object/0,
               json_object/0,
               json_object_members/0,
               json_object_members/0,
-              json_boolean/0,
+              json_object_format_tuple/0,
+              json_object_format_proplist/0,
 
 
               encode_option/0,
               encode_option/0,
               decode_option/0
               decode_option/0
@@ -57,19 +59,21 @@
 -type json_number()         :: number().
 -type json_number()         :: number().
 -type json_string()         :: binary() | atom(). % NOTE: `decode/1' always returns `binary()' value
 -type json_string()         :: binary() | atom(). % NOTE: `decode/1' always returns `binary()' value
 -type json_array()          :: [json_value()].
 -type json_array()          :: [json_value()].
--type json_object()         :: {json_object_members()}
-                             | [{}]
-                             | json_object_members().
+-type json_object()         :: json_object_format_tuple() | json_object_format_proplist().
 -type json_object_members() :: [{json_string(), json_value()}].
 -type json_object_members() :: [{json_string(), json_value()}].
 
 
+-type json_object_format_tuple() :: {json_object_members()}.
+-type json_object_format_proplist() :: [{}] | json_object_members().
+
 -type encode_option() :: native_utf8.
 -type encode_option() :: native_utf8.
 %% native_utf8: Encodes UTF-8 characters as a human-readable(non-escaped) string
 %% native_utf8: Encodes UTF-8 characters as a human-readable(non-escaped) string
 
 
--type decode_option() :: {format, eep18 | proplist}.
-%% TODO: doc
-
--define(DEFAULT_ENCODE_OPTIONS, []).
--define(DEFAULT_DECODE_OPTIONS, []).
+-type decode_option() :: {object_format, tuple | proplist}.
+%% object_format: <br />
+%%  - Decoded JSON object format <br />
+%%  - `tuple': An object is decoded as `{[]}' if it is empty, otherwise `{[{Key, Value}]}'. <br />
+%%  - `proplist': An object is decoded as `[{}]' if it is empty, otherwise `[{Key, Value}]'. <br />
+%%  - default: `tuple' <br />
 
 
 %%--------------------------------------------------------------------------------
 %%--------------------------------------------------------------------------------
 %% Exported Functions
 %% Exported Functions
@@ -77,7 +81,7 @@
 %% @equiv decode(Json, [])
 %% @equiv decode(Json, [])
 -spec decode(binary()) -> json_value().
 -spec decode(binary()) -> json_value().
 decode(Json) ->
 decode(Json) ->
-    decode(Json, ?DEFAULT_DECODE_OPTIONS).
+    decode(Json, []).
 
 
 %% @doc Decodes an erlang term from json text (a utf8 encoded binary)
 %% @doc Decodes an erlang term from json text (a utf8 encoded binary)
 %%
 %%
@@ -106,7 +110,7 @@ decode(Json, Options) ->
 %% @equiv try_decode(Json, [])
 %% @equiv try_decode(Json, [])
 -spec try_decode(binary()) -> {ok, json_value(), Remainings::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 -spec try_decode(binary()) -> {ok, json_value(), Remainings::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 try_decode(Json) ->
 try_decode(Json) ->
-    try_decode(Json, ?DEFAULT_DECODE_OPTIONS).
+    try_decode(Json, []).
 
 
 %% @doc Decodes an erlang term from json text (a utf8 encoded binary)
 %% @doc Decodes an erlang term from json text (a utf8 encoded binary)
 %%
 %%
@@ -126,7 +130,7 @@ try_decode(Json, Options) ->
 %% @equiv encode(JsonValue, [])
 %% @equiv encode(JsonValue, [])
 -spec encode(json_value()) -> binary().
 -spec encode(json_value()) -> binary().
 encode(JsonValue) ->
 encode(JsonValue) ->
-    encode(JsonValue, ?DEFAULT_ENCODE_OPTIONS).
+    encode(JsonValue, []).
 
 
 %% @doc Encodes an erlang term into json text (a utf8 encoded binary)
 %% @doc Encodes an erlang term into json text (a utf8 encoded binary)
 %%
 %%
@@ -155,7 +159,7 @@ encode(JsonValue, Options) ->
 %% @equiv try_encode(JsonValue, [])
 %% @equiv try_encode(JsonValue, [])
 -spec try_encode(json_value()) -> {ok, binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 -spec try_encode(json_value()) -> {ok, binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 try_encode(JsonValue) ->
 try_encode(JsonValue) ->
-    jsone_encode:encode(JsonValue, ?DEFAULT_ENCODE_OPTIONS).
+    try_encode(JsonValue, []).
 
 
 %% @doc Encodes an erlang term into json text (a utf8 encoded binary)
 %% @doc Encodes an erlang term into json text (a utf8 encoded binary)
 %%
 %%

+ 11 - 8
src/jsone_decode.erl

@@ -2,7 +2,7 @@
 %%% @private
 %%% @private
 %%% @end
 %%% @end
 %%%
 %%%
-%%% Copyright (c) 2013-2014, Takeru Ohta <phjgt308@gmail.com>
+%%% Copyright (c) 2013-2015, Takeru Ohta <phjgt308@gmail.com>
 %%%
 %%%
 %%% The MIT License
 %%% The MIT License
 %%%
 %%%
@@ -51,7 +51,7 @@
 
 
 -type decode_result() :: {ok, jsone:json_value(), Rest::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 -type decode_result() :: {ok, jsone:json_value(), Rest::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 
 
--record(decode_opt_v1, { format=eep18 :: eep18 | proplist}).
+-record(decode_opt_v1, { object_format=tuple :: tuple | proplist}).
 -define(OPT, #decode_opt_v1).
 -define(OPT, #decode_opt_v1).
 -type opt() :: #decode_opt_v1{}.
 -type opt() :: #decode_opt_v1{}.
 
 
@@ -115,8 +115,7 @@ array_next(<<$,, Bin/binary>>, Values, Nexts, Buf, Opt) -> whitespace(Bin, value
 array_next(Bin,                Values, Nexts, Buf, Opt) -> ?ERROR(array_next, [Bin, Values, Nexts, Buf, Opt]).
 array_next(Bin,                Values, Nexts, Buf, Opt) -> ?ERROR(array_next, [Bin, Values, Nexts, Buf, Opt]).
 
 
 -spec object(binary(), [next()], binary(), opt()) -> decode_result().
 -spec object(binary(), [next()], binary(), opt()) -> decode_result().
-object(<<$}, Bin/binary>>, Nexts, Buf, Opt = ?OPT{format = proplist}) -> next(Bin, [{}], Nexts, Buf, Opt);
-object(<<$}, Bin/binary>>, Nexts, Buf, Opt) -> next(Bin, {[]}, Nexts, Buf, Opt);
+object(<<$}, Bin/binary>>, Nexts, Buf, Opt) -> next(Bin, make_object([], Opt), Nexts, Buf, Opt);
 object(<<Bin/binary>>, Nexts, Buf, Opt)     -> object_key(Bin, [], Nexts, Buf, Opt).
 object(<<Bin/binary>>, Nexts, Buf, Opt)     -> object_key(Bin, [], Nexts, Buf, Opt).
 
 
 -spec object_key(binary(), jsone:json_object_members(), [next()], binary(), opt()) -> decode_result().
 -spec object_key(binary(), jsone:json_object_members(), [next()], binary(), opt()) -> decode_result().
@@ -128,8 +127,7 @@ object_value(<<$:, Bin/binary>>, Key, Members, Nexts, Buf, Opt) -> whitespace(Bi
 object_value(Bin,                Key, Members, Nexts, Buf, Opt) -> ?ERROR(object_value, [Bin, Key, Members, Nexts, Buf, Opt]).
 object_value(Bin,                Key, Members, Nexts, Buf, Opt) -> ?ERROR(object_value, [Bin, Key, Members, Nexts, Buf, Opt]).
 
 
 -spec object_next(binary(), jsone:json_object_members(), [next()], binary(), opt()) -> decode_result().
 -spec object_next(binary(), jsone:json_object_members(), [next()], binary(), opt()) -> decode_result().
-object_next(<<$}, Bin/binary>>, Members, Nexts, Buf, Opt = ?OPT{format = proplist}) -> next(Bin, lists:reverse(Members), Nexts, Buf, Opt);
-object_next(<<$}, Bin/binary>>, Members, Nexts, Buf, Opt) -> next(Bin, {lists:reverse(Members)}, Nexts, Buf, Opt);
+object_next(<<$}, Bin/binary>>, Members, Nexts, Buf, Opt) -> next(Bin, make_object(lists:reverse(Members), Opt), Nexts, Buf, Opt);
 object_next(<<$,, Bin/binary>>, Members, Nexts, Buf, Opt) -> whitespace(Bin, {object_key, Members}, Nexts, Buf, Opt);
 object_next(<<$,, Bin/binary>>, Members, Nexts, Buf, Opt) -> whitespace(Bin, {object_key, Members}, Nexts, Buf, Opt);
 object_next(Bin,                Members, Nexts, Buf, Opt) -> ?ERROR(object_next, [Bin, Members, Nexts, Buf, Opt]).
 object_next(Bin,                Members, Nexts, Buf, Opt) -> ?ERROR(object_next, [Bin, Members, Nexts, Buf, Opt]).
 
 
@@ -265,11 +263,16 @@ number_exponation_part(<<Bin/binary>>, N, DecimalOffset, ExpSign, Exp, false, Ne
 number_exponation_part(Bin, N, DecimalOffset, ExpSign, Exp, IsFirst, Nexts, Buf, Opt) ->
 number_exponation_part(Bin, N, DecimalOffset, ExpSign, Exp, IsFirst, Nexts, Buf, Opt) ->
     ?ERROR(number_exponation_part, [Bin, N, DecimalOffset, ExpSign, Exp, IsFirst, Nexts, Buf, Opt]).
     ?ERROR(number_exponation_part, [Bin, N, DecimalOffset, ExpSign, Exp, IsFirst, Nexts, Buf, Opt]).
 
 
+-spec make_object(jsone:json_object_members(), opt()) -> jsone:json_object().
+make_object(Members, ?OPT{object_format = tuple}) -> {Members};
+make_object([],      _)                           -> [{}];
+make_object(Members, _)                           -> Members.
+
 -spec parse_options([jsone:decode_option()]) -> opt().
 -spec parse_options([jsone:decode_option()]) -> opt().
 parse_options(Options) ->
 parse_options(Options) ->
     parse_option(Options, ?OPT{}).
     parse_option(Options, ?OPT{}).
 
 
 -spec parse_option([jsone:decode_option()], opt()) -> opt().
 -spec parse_option([jsone:decode_option()], opt()) -> opt().
 parse_option([], Opt) -> Opt;
 parse_option([], Opt) -> Opt;
-parse_option([{format,F}|T], Opt) ->
-    parse_option(T, Opt?OPT{format=F}).
+parse_option([{object_format,F}|T], Opt) when F =:= tuple; F =:= proplist ->
+    parse_option(T, Opt?OPT{object_format=F}).

+ 30 - 30
src/jsone_encode.erl

@@ -2,7 +2,7 @@
 %%% @private
 %%% @private
 %%% @end
 %%% @end
 %%%
 %%%
-%%% Copyright (c) 2013-2014, Takeru Ohta <phjgt308@gmail.com>
+%%% Copyright (c) 2013-2015, Takeru Ohta <phjgt308@gmail.com>
 %%%
 %%%
 %%% The MIT License
 %%% The MIT License
 %%%
 %%%
@@ -39,6 +39,7 @@
 -define(IS_REDUNDANT_UTF8(B1, B2, FirstBitN), (B1 =:= 0 andalso B2 < (1 bsl (FirstBitN + 1)))).
 -define(IS_REDUNDANT_UTF8(B1, B2, FirstBitN), (B1 =:= 0 andalso B2 < (1 bsl (FirstBitN + 1)))).
 -define(HEX(N, I), (binary:at(<<"0123456789abcdef">>, (N bsr (I * 4)) band 2#1111))).
 -define(HEX(N, I), (binary:at(<<"0123456789abcdef">>, (N bsr (I * 4)) band 2#1111))).
 -define(UNICODE_TO_HEX(Code), ?HEX(Code, 3), ?HEX(Code, 2), ?HEX(Code, 1), ?HEX(Code, 0)).
 -define(UNICODE_TO_HEX(Code), ?HEX(Code, 3), ?HEX(Code, 2), ?HEX(Code, 1), ?HEX(Code, 0)).
+-define(IS_STR(X), is_binary(X); is_atom(X)).
 
 
 -type encode_result() :: {ok, binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 -type encode_result() :: {ok, binary()} | {error, {Reason::term(), [erlang:stack_item()]}}.
 -type next() :: {array_values, [jsone:json_value()]}
 -type next() :: {array_values, [jsone:json_value()]}
@@ -46,8 +47,8 @@
               | {object_members, jsone:json_object_members()}.
               | {object_members, jsone:json_object_members()}.
 
 
 -record(encode_opt_v1, { native_utf8 = false :: boolean() }).
 -record(encode_opt_v1, { native_utf8 = false :: boolean() }).
--define(ENCODE_OPT, #encode_opt_v1).
--type encode_opt() :: #encode_opt_v1{}.
+-define(OPT, #encode_opt_v1).
+-type opt() :: #encode_opt_v1{}.
 
 
 %%--------------------------------------------------------------------------------
 %%--------------------------------------------------------------------------------
 %% Exported Functions
 %% Exported Functions
@@ -64,7 +65,7 @@ encode(Value, Options) ->
 %%--------------------------------------------------------------------------------
 %%--------------------------------------------------------------------------------
 %% Internal Functions
 %% Internal Functions
 %%--------------------------------------------------------------------------------
 %%--------------------------------------------------------------------------------
--spec next([next()], binary(), encode_opt()) -> encode_result().
+-spec next([next()], binary(), opt()) -> encode_result().
 next([], Buf, _)             -> {ok, Buf};
 next([], Buf, _)             -> {ok, Buf};
 next([Next | Nexts], Buf, Opt) ->
 next([Next | Nexts], Buf, Opt) ->
     case Next of
     case Next of
@@ -82,25 +83,26 @@ next([Next | Nexts], Buf, Opt) ->
             end
             end
     end.
     end.
 
 
--spec value(jsone:json_value(), [next()], binary(), encode_opt()) -> encode_result().
+-spec value(jsone:json_value(), [next()], binary(), opt()) -> encode_result().
 value(null, Nexts, Buf, Opt)                         -> next(Nexts, <<Buf/binary, "null">>, Opt);
 value(null, Nexts, Buf, Opt)                         -> next(Nexts, <<Buf/binary, "null">>, Opt);
 value(false, Nexts, Buf, Opt)                        -> next(Nexts, <<Buf/binary, "false">>, Opt);
 value(false, Nexts, Buf, Opt)                        -> next(Nexts, <<Buf/binary, "false">>, Opt);
 value(true, Nexts, Buf, Opt)                         -> next(Nexts, <<Buf/binary, "true">>, Opt);
 value(true, Nexts, Buf, Opt)                         -> next(Nexts, <<Buf/binary, "true">>, Opt);
-value(Value, Nexts, Buf, Opt) when is_atom(Value)    -> string(atom_to_binary(Value, utf8), Nexts, Buf, Opt);
 value(Value, Nexts, Buf, Opt) when is_integer(Value) -> next(Nexts, <<Buf/binary, (integer_to_binary(Value))/binary>>, Opt);
 value(Value, Nexts, Buf, Opt) when is_integer(Value) -> next(Nexts, <<Buf/binary, (integer_to_binary(Value))/binary>>, Opt);
 value(Value, Nexts, Buf, Opt) when is_float(Value)   -> next(Nexts, <<Buf/binary, (float_to_binary(Value))/binary>>, Opt);
 value(Value, Nexts, Buf, Opt) when is_float(Value)   -> next(Nexts, <<Buf/binary, (float_to_binary(Value))/binary>>, Opt);
-value(Value, Nexts, Buf, Opt) when is_binary(Value)  -> string(Value, Nexts, Buf, Opt);
-value({_} = Value, Nexts, Buf, Opt)                  -> object(Value, Nexts, Buf, Opt);
-value([{}], Nexts, Buf, Opt)                         -> object({[]}, Nexts, Buf, Opt);
-value([{_, _}|_] = Value, Nexts, Buf, Opt)           -> object({Value}, Nexts, Buf, Opt);
+value(Value, Nexts, Buf, Opt) when ?IS_STR(Value)    -> string(Value, Nexts, Buf, Opt);
+value({Value}, Nexts, Buf, Opt)                      -> object(Value, Nexts, Buf, Opt);
+value([{}], Nexts, Buf, Opt)                         -> object([], Nexts, Buf, Opt);
+value([{_, _}|_] = Value, Nexts, Buf, Opt)           -> object(Value, Nexts, Buf, Opt);
 value(Value, Nexts, Buf, Opt) when is_list(Value)    -> array(Value, Nexts, Buf, Opt);
 value(Value, Nexts, Buf, Opt) when is_list(Value)    -> array(Value, Nexts, Buf, Opt);
-value(Value, Nexts, Buf, _)                        -> ?ERROR(value, [Value, Nexts, Buf]).
+value(Value, Nexts, Buf, _)                          -> ?ERROR(value, [Value, Nexts, Buf]).
 
 
--spec string(jsone:json_string(), [next()], binary(), encode_opt()) -> encode_result().
+-spec string(jsone:json_string(), [next()], binary(), opt()) -> encode_result().
 string(<<Str/binary>>, Nexts, Buf, Opt) ->
 string(<<Str/binary>>, Nexts, Buf, Opt) ->
-    escape_string(Str, Nexts, <<Buf/binary, $">>, Opt).
+    escape_string(Str, Nexts, <<Buf/binary, $">>, Opt);
+string(Str, Nexts, Buf, Opt) ->
+    string(atom_to_binary(Str, utf8), Nexts, Buf, Opt).
 
 
--spec escape_string(binary(), [next()], binary(), encode_opt()) -> encode_result().
+-spec escape_string(binary(), [next()], binary(), opt()) -> encode_result().
 escape_string(<<"">>,                   Nexts, Buf, Opt) -> next(Nexts, <<Buf/binary, $">>, Opt);
 escape_string(<<"">>,                   Nexts, Buf, Opt) -> next(Nexts, <<Buf/binary, $">>, Opt);
 escape_string(<<$", Str/binary>>,       Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $">>, Opt);
 escape_string(<<$", Str/binary>>,       Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $">>, Opt);
 escape_string(<<$\/, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $\/>>, Opt);
 escape_string(<<$\/, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $\/>>, Opt);
@@ -112,7 +114,7 @@ escape_string(<<$\r, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, N
 escape_string(<<$\t, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $t>>, Opt);
 escape_string(<<$\t, Str/binary>>,      Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, $\\, $t>>, Opt);
 escape_string(<<0:1, C:7, Str/binary>>, Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, C>>, Opt);
 escape_string(<<0:1, C:7, Str/binary>>, Nexts, Buf, Opt) -> escape_string(Str, Nexts, <<Buf/binary, C>>, Opt);
 escape_string(<<2#110:3, B1:5, 2#10:2, B2:6, Str/binary>>, Nexts, Buf, Opt) when not ?IS_REDUNDANT_UTF8(B1, B2, 5) ->
 escape_string(<<2#110:3, B1:5, 2#10:2, B2:6, Str/binary>>, Nexts, Buf, Opt) when not ?IS_REDUNDANT_UTF8(B1, B2, 5) ->
-    case Opt?ENCODE_OPT.native_utf8 of
+    case Opt?OPT.native_utf8 of
         false ->
         false ->
             Unicode = (B1 bsl 6) + B2,
             Unicode = (B1 bsl 6) + B2,
             escape_unicode_char(Str, Unicode, Nexts, Buf, Opt);
             escape_unicode_char(Str, Unicode, Nexts, Buf, Opt);
@@ -120,7 +122,7 @@ escape_string(<<2#110:3, B1:5, 2#10:2, B2:6, Str/binary>>, Nexts, Buf, Opt) when
             unicode_char(Str, <<2#110:3, B1:5, 2#10:2, B2:6>>, Nexts, Buf, Opt)
             unicode_char(Str, <<2#110:3, B1:5, 2#10:2, B2:6>>, Nexts, Buf, Opt)
     end;
     end;
 escape_string(<<2#1110:4, B1:4, 2#10:2, B2:6, 2#10:2, B3:6, Str/binary>>, Nexts, Buf, Opt) when not ?IS_REDUNDANT_UTF8(B1, B2, 4) ->
 escape_string(<<2#1110:4, B1:4, 2#10:2, B2:6, 2#10:2, B3:6, Str/binary>>, Nexts, Buf, Opt) when not ?IS_REDUNDANT_UTF8(B1, B2, 4) ->
-    case Opt?ENCODE_OPT.native_utf8 of
+    case Opt?OPT.native_utf8 of
         false ->
         false ->
             Unicode = (B1 bsl 12) + (B2 bsl 6) + B3,
             Unicode = (B1 bsl 12) + (B2 bsl 6) + B3,
             escape_unicode_char(Str, Unicode, Nexts, Buf, Opt);
             escape_unicode_char(Str, Unicode, Nexts, Buf, Opt);
@@ -128,7 +130,7 @@ escape_string(<<2#1110:4, B1:4, 2#10:2, B2:6, 2#10:2, B3:6, Str/binary>>, Nexts,
             unicode_char(Str, <<2#1110:4, B1:4, 2#10:2, B2:6, 2#10:2, B3:6>>, Nexts, Buf, Opt)
             unicode_char(Str, <<2#1110:4, B1:4, 2#10:2, B2:6, 2#10:2, B3:6>>, Nexts, Buf, Opt)
     end;
     end;
 escape_string(<<2#11110:5, B1:3, 2#10:2, B2:6, 2#10:2, B3:6, 2#10:2, B4:6, Str/binary>>, Nexts, Buf, Opt) when not ?IS_REDUNDANT_UTF8(B1, B2, 3) ->
 escape_string(<<2#11110:5, B1:3, 2#10:2, B2:6, 2#10:2, B3:6, 2#10:2, B4:6, Str/binary>>, Nexts, Buf, Opt) when not ?IS_REDUNDANT_UTF8(B1, B2, 3) ->
-    case Opt?ENCODE_OPT.native_utf8 of
+    case Opt?OPT.native_utf8 of
         false ->
         false ->
             Unicode = (B1 bsl 18) + (B2 bsl 12) + (B3 bsl 6) + B4,
             Unicode = (B1 bsl 18) + (B2 bsl 12) + (B3 bsl 6) + B4,
             escape_unicode_char(Str, Unicode, Nexts, Buf, Opt);
             escape_unicode_char(Str, Unicode, Nexts, Buf, Opt);
@@ -141,7 +143,7 @@ escape_string(Str, Nexts, Buf, _) ->
 unicode_char(Str, Char, Nexts, Buf, Opt) ->
 unicode_char(Str, Char, Nexts, Buf, Opt) ->
     escape_string(Str, Nexts, <<Buf/binary, Char/binary>>, Opt).
     escape_string(Str, Nexts, <<Buf/binary, Char/binary>>, Opt).
 
 
--spec escape_unicode_char(binary(), char(), [next()], binary(), encode_opt()) -> encode_result().
+-spec escape_unicode_char(binary(), char(), [next()], binary(), opt()) -> encode_result().
 escape_unicode_char(<<Str/binary>>, Unicode, Nexts, Buf, Opt) when Unicode =< 16#FFFF ->
 escape_unicode_char(<<Str/binary>>, Unicode, Nexts, Buf, Opt) when Unicode =< 16#FFFF ->
     escape_string(Str, Nexts, <<Buf/binary, $\\, $u, ?UNICODE_TO_HEX(Unicode)>>, Opt);
     escape_string(Str, Nexts, <<Buf/binary, $\\, $u, ?UNICODE_TO_HEX(Unicode)>>, Opt);
 escape_unicode_char(<<Str/binary>>, Unicode, Nexts, Buf, Opt) ->
 escape_unicode_char(<<Str/binary>>, Unicode, Nexts, Buf, Opt) ->
@@ -149,33 +151,31 @@ escape_unicode_char(<<Str/binary>>, Unicode, Nexts, Buf, Opt) ->
     <<High:10, Low:10>> = <<(Unicode - 16#10000):20>>, % XXX: inefficient
     <<High:10, Low:10>> = <<(Unicode - 16#10000):20>>, % XXX: inefficient
     escape_string(Str, Nexts, <<Buf/binary, $\\, $u, ?UNICODE_TO_HEX(High + 16#D800), $\\, $u, ?UNICODE_TO_HEX(Low + 16#DC00)>>, Opt).
     escape_string(Str, Nexts, <<Buf/binary, $\\, $u, ?UNICODE_TO_HEX(High + 16#D800), $\\, $u, ?UNICODE_TO_HEX(Low + 16#DC00)>>, Opt).
 
 
--spec array(jsone:json_array(), [next()], binary(), encode_opt()) -> encode_result().
+-spec array(jsone:json_array(), [next()], binary(), opt()) -> encode_result().
 array(List, Nexts, Buf, Opt) ->
 array(List, Nexts, Buf, Opt) ->
     array_values(List, Nexts, <<Buf/binary, $[>>, Opt).
     array_values(List, Nexts, <<Buf/binary, $[>>, Opt).
 
 
--spec array_values(jsone:json_array(), [next()], binary(), encode_opt()) -> encode_result().
+-spec array_values(jsone:json_array(), [next()], binary(), opt()) -> encode_result().
 array_values([],       Nexts, Buf, Opt) -> next(Nexts, <<Buf/binary, $]>>, Opt);
 array_values([],       Nexts, Buf, Opt) -> next(Nexts, <<Buf/binary, $]>>, Opt);
 array_values([X | Xs], Nexts, Buf, Opt) -> value(X, [{array_values, Xs} | Nexts], Buf, Opt).
 array_values([X | Xs], Nexts, Buf, Opt) -> value(X, [{array_values, Xs} | Nexts], Buf, Opt).
 
 
--spec object(jsone:json_object(), [next()], binary(), encode_opt()) -> encode_result().
-object({Members}, Nexts, Buf, Opt) ->
+-spec object(jsone:json_object_members(), [next()], binary(), opt()) -> encode_result().
+object(Members, Nexts, Buf, Opt) ->
     object_members(Members, Nexts, <<Buf/binary, ${>>, Opt).
     object_members(Members, Nexts, <<Buf/binary, ${>>, Opt).
 
 
--spec object_members(jsone:json_object_members(), [next()], binary(), encode_opt()) -> encode_result().
+-spec object_members(jsone:json_object_members(), [next()], binary(), opt()) -> encode_result().
 object_members([],                             Nexts, Buf, Opt)        -> next(Nexts, <<Buf/binary, $}>>, Opt);
 object_members([],                             Nexts, Buf, Opt)        -> next(Nexts, <<Buf/binary, $}>>, Opt);
-object_members([{<<Key/binary>>, Value} | Xs], Nexts, Buf, Opt)        -> string(Key, [{object_value, Value, Xs} | Nexts], Buf, Opt);
-object_members([{Key, Value} | Xs], Nexts, Buf, Opt) when is_atom(Key) -> string(atom_to_binary(Key, utf8), [{object_value, Value, Xs} | Nexts], Buf, Opt);
+object_members([{Key, Value} | Xs], Nexts, Buf, Opt) when ?IS_STR(Key) -> string(Key, [{object_value, Value, Xs} | Nexts], Buf, Opt);
 object_members(Arg, Nexts, Buf, _)                                     -> ?ERROR(object_members, [Arg, Nexts, Buf]).
 object_members(Arg, Nexts, Buf, _)                                     -> ?ERROR(object_members, [Arg, Nexts, Buf]).
 
 
--spec object_value(jsone:json_value(), jsone:json_object_members(), [next()], binary(), encode_opt()) -> encode_result().
+-spec object_value(jsone:json_value(), jsone:json_object_members(), [next()], binary(), opt()) -> encode_result().
 object_value(Value, Members, Nexts, Buf, Opt) ->
 object_value(Value, Members, Nexts, Buf, Opt) ->
     value(Value, [{object_members, Members} | Nexts], <<Buf/binary, $:>>, Opt).
     value(Value, [{object_members, Members} | Nexts], <<Buf/binary, $:>>, Opt).
 
 
-
--spec parse_options([jsone:encode_option()]) -> encode_opt().
+-spec parse_options([jsone:encode_option()]) -> opt().
 parse_options(Options) ->
 parse_options(Options) ->
-    parse_option(Options, ?ENCODE_OPT{}).
+    parse_option(Options, ?OPT{}).
 
 
 parse_option([], Opt) -> Opt;
 parse_option([], Opt) -> Opt;
 parse_option([native_utf8|T], Opt) ->
 parse_option([native_utf8|T], Opt) ->
-    parse_option(T, Opt?ENCODE_OPT{native_utf8=true}).
+    parse_option(T, Opt?OPT{native_utf8=true}).

+ 3 - 3
test/jsone_decode_tests.erl

@@ -1,4 +1,4 @@
-%% Copyright (c) 2013-2014, Takeru Ohta <phjgt308@gmail.com>
+%% Copyright (c) 2013-2015, Takeru Ohta <phjgt308@gmail.com>
 %% coding: latin-1
 %% coding: latin-1
 -module(jsone_decode_tests).
 -module(jsone_decode_tests).
 
 
@@ -164,7 +164,7 @@ decode_test_() ->
               Input    = <<"{\"1\":2,\"key\":\"value\"}">>,
               Input    = <<"{\"1\":2,\"key\":\"value\"}">>,
               Expected = {[{<<"1">>, 2},{<<"key">>, <<"value">>}]},
               Expected = {[{<<"1">>, 2},{<<"key">>, <<"value">>}]},
               ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input)),
               ?assertEqual({ok, Expected, <<"">>}, jsone_decode:decode(Input)),
-              ?assertEqual({ok, element(1, Expected), <<"">>}, jsone_decode:decode(Input, [{format, proplist}]))
+              ?assertEqual({ok, element(1, Expected), <<"">>}, jsone_decode:decode(Input, [{object_format, proplist}]))
       end},
       end},
      {"object: contains whitespaces",
      {"object: contains whitespaces",
       fun () ->
       fun () ->
@@ -176,7 +176,7 @@ decode_test_() ->
       fun () ->
       fun () ->
               ?assertEqual({ok, {[]}, <<"">>}, jsone_decode:decode(<<"{}">>)),
               ?assertEqual({ok, {[]}, <<"">>}, jsone_decode:decode(<<"{}">>)),
               ?assertEqual({ok, {[]}, <<"">>}, jsone_decode:decode(<<"{ \t\r\n}">>)),
               ?assertEqual({ok, {[]}, <<"">>}, jsone_decode:decode(<<"{ \t\r\n}">>)),
-              ?assertEqual({ok, [{}], <<"">>}, jsone_decode:decode(<<"{}">>, [{format, proplist}]))
+              ?assertEqual({ok, [{}], <<"">>}, jsone_decode:decode(<<"{}">>, [{object_format, proplist}]))
       end},
       end},
      {"object: trailing comma is disallowed",
      {"object: trailing comma is disallowed",
       fun () ->
       fun () ->