# Module jsone # * [Description](#description) * [Data Types](#types) * [Function Index](#index) * [Function Details](#functions) JSON decoding/encoding module. ## Data Types ## ### datetime_encode_format() ###

datetime_encode_format() = datetime_format() | {Format::datetime_format(), TimeZone::timezone()}
Datetime encoding format. The default value of `TimeZone` is `utc`. ``` % % Universal Time % > jsone:encode({{2000, 3, 10}, {10, 3, 58}}, [{datetime_format, iso8601}]). <<"\"2000-03-10T10:03:58Z\"">> % % Local Time (JST) % > jsone:encode({{2000, 3, 10}, {10, 3, 58}}, [{datetime_format, {iso8601, local}}]). <<"\"2000-03-10T10:03:58+09:00\"">> % % Explicit TimeZone Offset % > jsone:encode({{2000, 3, 10}, {10, 3, 58}}, [{datetime_format, {iso8601, -2*60*60}}]). <<"\"2000-03-10T10:03:58-02:00\"">> ``` ### datetime_format() ###

datetime_format() = iso8601
### decode_option() ###

decode_option() = {object_format, tuple | proplist | map} | {allow_ctrl_chars, boolean()} | {keys, binary | atom | existing_atom | attempt_atom}
`object_format`:
- Decoded JSON object format
- `tuple`: An object is decoded as `{[]}` if it is empty, otherwise `{[{Key, Value}]}`.
- `proplist`: An object is decoded as `[{}]` if it is empty, otherwise `[{Key, Value}]`.
- `map`: An object is decoded as `#{}` if it is empty, otherwise `#{Key => Value}`.
- default: `map` if OTP version is OTP-17 or more, `tuple` otherwise
`allow_ctrl_chars`:
- If the value is `true`, strings which contain ununescaped control characters will be regarded as a legal JSON string
- default: `false`
`keys`:
Defines way how object keys are decoded. The default value is `binary`. The option is compatible with `labels` option in `jsx`.
- `binary`: The key is left as a string which is encoded as binary. It's default and backward compatible behaviour.
- `atom`: The key is converted to an atom. Results in `badarg` if Key value regarded as UTF-8 is not a valid atom.
- `existing_atom`: Returns existing atom. Any key value which is not existing atom raises `badarg` exception.
- `attempt_atom`: Returns existing atom as `existing_atom` but returns a binary string if fails find one. ### encode_option() ###

encode_option() = native_utf8 | {float_format, [float_format_option()]} | {datetime_format, datetime_encode_format()} | {object_key_type, string | scalar | value} | {space, non_neg_integer()} | {indent, non_neg_integer()}
`native_utf8`:
- Encodes UTF-8 characters as a human-readable(non-escaped) string
`{float_format, Optoins}`: - Encodes a `float()` value in the format which specified by `Options`
- default: `[{scientific, 20}]`
`{datetime_format, Format}`: - Encodes a `calendar:datetime()` value in the format which specified by `Format`
- default: `{iso8601, utc}`
`object_key_type`: - Allowable object key type
- `string`: Only string values are allowed (i.e. `json_string()` type)
- `scalar`: In addition to `string`, following values are allowed: nulls, booleans, numerics (i.e. `json_scalar()` type)
- `value`: Any json compatible values are allowed (i.e. `json_value()` type)
- default: `string`
- NOTE: If `scalar` or `value` option is specified, non `json_string()` key will be automatically converted to a `binary()` value (e.g. `1` => `<<"1">>`, `#{}` => `<<"{}">>`)
`{space, N}`:
- Inserts `N` spaces after every commna and colon
- default: `0`
`{indent, N}`:
- Inserts a newline and `N` spaces for each level of indentation
- default: `0`
### float_format_option() ###

float_format_option() = {scientific, Decimals::0..249} | {decimals, Decimals::0..253} | compact
`scientific`:
- The float will be formatted using scientific notation with `Decimals` digits of precision.
`decimals`:
- The encoded string will contain at most `Decimals` number of digits past the decimal point.
- If `compact` is provided the trailing zeros at the end of the string are truncated.
For more details, see [erlang:flaot_to_list/2](http://erlang.org/doc/man/erlang.md#float_to_list-2). ``` > jsone:encode(1.23). <<"1.22999999999999998224e+00">> > jsone:encode(1.23, [{float_format, [{scientific, 4}]}]). <"1.2300e+00">> > jsone:encode(1.23, [{float_format, [{scientific, 1}]}]). <<"1.2e+00">> > jsone:encode(1.23, [{float_format, [{decimals, 4}]}]). <<"1.2300">> > jsone:encode(1.23, [{float_format, [{decimals, 4}, compact]}]). <<"1.23">> ``` ### json_array() ###

json_array() = [json_value()]
### json_boolean() ###

json_boolean() = boolean()
### json_number() ###

json_number() = number()
### json_object() ###

json_object() = json_object_format_tuple() | json_object_format_proplist() | json_object_format_map()
### json_object_format_map() ###

json_object_format_map() = #{}
### json_object_format_proplist() ###

json_object_format_proplist() = [{}] | json_object_members()
### json_object_format_tuple() ###

json_object_format_tuple() = {json_object_members()}
### json_object_members() ###

json_object_members() = [{json_string(), json_value()}]
### json_scalar() ###

json_scalar() = json_boolean() | json_number() | json_string()
### json_string() ###

json_string() = binary() | atom() | calendar:datetime()
NOTE: `decode/1` always returns `binary()` value ### json_term() ###

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 variants except `json_utf8` will check if binary contain valid `UTF-8` encoded data. In short, `json` uses `erlang:iolist_to_binary/1` and `json_utf8` uses `unicode:chardata_to_binary/1` for encoding. A simple example is worth a thousand words. ``` 1> S = "hélo". "hélo" 2> shell:strings(false). true 3> S. [104,233,108,111] 4> B = jsone:encode({{json, S}}). % invalid UTF-8 <<104,233,108,111>> 5> B2 = jsone:encode({{json_utf8, S}}). % valid UTF-8 <<104,195,169,108,111>> 6> jsone:encode({{json, B}}). <<104,233,108,111>> 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>>}, [],<<>>, {encode_opt_v2,false, [{scientific,20}], {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}}). <<104,195,169,108,111>> 9> shell:strings(true). false 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 <<"hélo"/utf8>> ``` ### json_value() ###

json_value() = json_number() | json_string() | json_array() | json_object() | json_boolean() | null | json_term()
### timezone() ###

timezone() = utc | local | utc_offset_seconds()
### utc_offset_seconds() ###

utc_offset_seconds() = -86399..86399
## Function Index ##
decode/1Equivalent to decode(Json, []).
decode/2Decodes an erlang term from json text (a utf8 encoded binary).
encode/1Equivalent to encode(JsonValue, []).
encode/2Encodes an erlang term into json text (a utf8 encoded binary).
try_decode/1Equivalent to try_decode(Json, []).
try_decode/2Decodes an erlang term from json text (a utf8 encoded binary).
try_encode/1Equivalent to try_encode(JsonValue, []).
try_encode/2Encodes an erlang term into json text (a utf8 encoded binary).
## Function Details ## ### decode/1 ###

decode(Json::binary()) -> json_value()

Equivalent to [`decode(Json, [])`](#decode-2). ### decode/2 ###

decode(Json::binary(), Options::[decode_option()]) -> json_value()

Decodes an erlang term from json text (a utf8 encoded binary) Raises an error exception if input is not valid json ``` > jsone:decode(<<"1">>, []). 1 > jsone:decode(<<"wrong json">>, []). ** exception error: bad argument in function jsone_decode:number_integer_part/4 called as jsone_decode:number_integer_part(<<"wrong json">>,1,[],<<>>) in call from jsone:decode/1 (src/jsone.erl, line 71) ``` ### encode/1 ###

encode(JsonValue::json_value()) -> binary()

Equivalent to [`encode(JsonValue, [])`](#encode-2). ### encode/2 ###

encode(JsonValue::json_value(), Options::[encode_option()]) -> binary()

Encodes an erlang term into json text (a utf8 encoded binary) Raises an error exception if input is not an instance of type `json_value()` ``` > jsone:encode([1, null, 2]). <<"[1,null,2]">> > jsone:encode([1, self(), 2]). % A pid is not a json value ** exception error: bad argument in function jsone_encode:value/3 called as jsone_encode:value(<0,34,0>,[{array_values,[2]}],<<"[1,">>) in call from jsone:encode/1 (src/jsone.erl, line 97) ``` ### try_decode/1 ###

try_decode(Json::binary()) -> {ok, json_value(), Remainings::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}

Equivalent to [`try_decode(Json, [])`](#try_decode-2). ### try_decode/2 ###

try_decode(Json::binary(), Options::[decode_option()]) -> {ok, json_value(), Remainings::binary()} | {error, {Reason::term(), [erlang:stack_item()]}}

Decodes an erlang term from json text (a utf8 encoded binary) ``` > jsone:try_decode(<<"[1,2,3] \"next value\"">>, []). {ok,[1,2,3],<<" \"next value\"">>} > jsone:try_decode(<<"wrong json">>, []). {error,{badarg,[{jsone_decode,number_integer_part, [<<"wrong json">>,1,[],<<>>], [{line,208}]}]}} ``` ### try_encode/1 ###

try_encode(JsonValue::json_value()) -> {ok, binary()} | {error, {Reason::term(), [erlang:stack_item()]}}

Equivalent to [`try_encode(JsonValue, [])`](#try_encode-2). ### try_encode/2 ###

try_encode(JsonValue::json_value(), Options::[encode_option()]) -> {ok, binary()} | {error, {Reason::term(), [erlang:stack_item()]}}

Encodes an erlang term into json text (a utf8 encoded binary) ``` > jsone:try_encode([1, null, 2]). {ok,<<"[1,null,2]">>} > jsone:try_encode([1, hoge, 2]). % 'hoge' atom is not a json value {error,{badarg,[{jsone_encode,value, [hoge,[{array_values,[2]}],<<"[1,">>], [{line,86}]}]}} ```