View Source json (json_polyfill v0.1.0)

Summary

Functions

Parses a JSON value from Binary.

Parses a JSON value from Binary.

Continue parsing a stream of bytes of a JSON value.

Begin parsing a stream of bytes of a JSON value.

Generates JSON corresponding to Term.

Generates JSON corresponding to Term.

Default encoder for atoms used by json:encode/1.

Default encoder for binaries as JSON strings used by json:encode/1.

Encoder for binaries as JSON strings producing pure-ASCII JSON.

Default encoder for floats as JSON numbers used by json:encode/1.
Default encoder for integers as JSON numbers used by json:encode/1.

Encoder for lists of key-value pairs as JSON objects.

Encoder for lists of key-value pairs as JSON objects.

Default encoder for lists as JSON arrays used by json:encode/1.

Default encoder for maps as JSON objects used by json:encode/1.

Encoder for maps as JSON objects.

Default encoder used by json:encode/1.

Types

-type acc() :: dynamic().
-type array_finish_fun() :: fun((ArrayAcc :: dynamic(), OldAcc :: dynamic()) -> {dynamic(), dynamic()}).
-type array_push_fun() :: fun((Value :: dynamic(), Acc :: dynamic()) -> NewAcc :: dynamic()).
-type array_start_fun() :: fun((Acc :: dynamic()) -> ArrayAcc :: dynamic()).
-opaque continuation_state()
-type decode() ::
    #decode{array_start :: array_start_fun() | undefined,
            array_push :: array_push_fun() | undefined,
            array_finish :: array_finish_fun() | undefined,
            object_start :: object_start_fun() | undefined,
            object_push :: object_push_fun() | undefined,
            object_finish :: object_finish_fun() | undefined,
            float :: from_binary_fun(),
            integer :: from_binary_fun(),
            string :: from_binary_fun() | undefined,
            null :: term()}.
-type decode_value() ::
    integer() |
    float() |
    boolean() |
    null |
    binary() |
    [decode_value()] |
    #{binary() => decode_value()}.
-type decoders() ::
    #{array_start => array_start_fun(),
      array_push => array_push_fun(),
      array_finish => array_finish_fun(),
      object_start => object_start_fun(),
      object_push => object_push_fun(),
      object_finish => object_finish_fun(),
      float => from_binary_fun(),
      integer => from_binary_fun(),
      string => from_binary_fun(),
      null => term()}.
-type encode_map(Value) :: #{binary() | atom() | integer() => Value}.
-type encode_value() ::
    integer() |
    float() |
    boolean() |
    null |
    binary() |
    atom() |
    [encode_value()] |
    encode_map(encode_value()).
Simple JSON value encodeable with json:encode/1.
-type encoder() :: fun((dynamic(), encoder()) -> iodata()).
-type from_binary_fun() :: fun((binary()) -> dynamic()).
-type object_finish_fun() ::
    fun((ObjectAcc :: dynamic(), OldAcc :: dynamic()) -> {dynamic(), dynamic()}).
-type object_push_fun() ::
    fun((Key :: dynamic(), Value :: dynamic(), Acc :: dynamic()) -> NewAcc :: dynamic()).
-type object_start_fun() :: fun((Acc :: dynamic()) -> ObjectAcc :: dynamic()).
-type stack() :: [array | object | binary() | acc()].

Functions

-spec decode(binary()) -> decode_value().

Parses a JSON value from Binary.

Supports basic data mapping:

| JSON | Erlang | |----------|------------------------| | Number | integer() \| float() | | Boolean | true \| false | | Null | null | | String | binary() | | Object | #{binary() => _} |

Errors

- error(unexpected_end) if Binary contains incomplete JSON value - error({invalid_byte, Byte}) if Binary contains unexpected byte or invalid UTF-8 byte - error({invalid_sequence, Bytes}) if Binary contains invalid UTF-8 escape

Example

  1> json:decode(<<"{\"foo\": 1}">>).
  #{<<"foo">> => 1}
Link to this function

decode(Binary, Acc0, Decoders)

View Source
-spec decode(binary(), dynamic(), decoders()) -> {Result :: dynamic(), Acc :: dynamic(), binary()}.

Parses a JSON value from Binary.

Similar to decode/1 except the decoding process can be customized with the callbacks specified in Decoders. The callbacks will use the Acc value as the initial accumulator.

Any leftover, unparsed data in Binary will be returned.

Default callbacks

All callbacks are optional. If not provided, they will fall back to implementations used by the decode/1 function:

- for array_start: fun(_) -> [] end - for array_push: fun(Elem, Acc) -> [Elem | Acc] end - for array_finish: fun(Acc, OldAcc) -> {lists:reverse(Acc), OldAcc} end - for object_start: fun(_) -> [] end - for object_push: fun(Key, Value, Acc) -> [{Key, Value} | Acc] end - for object_finish: fun(Acc, OldAcc) -> {maps:from_list(Acc), OldAcc} end - for float: fun erlang:binary_to_float/1 - for integer: fun erlang:binary_to_integer/1 - for string: fun (Value) -> Value end - for null: the atom null

Errors

- error({invalid_byte, Byte}) if Binary contains unexpected byte or invalid UTF-8 byte - error({invalid_sequence, Bytes}) if Binary contains invalid UTF-8 escape - error(unexpected_end) if Binary contains incomplete JSON value

Example

Decoding object keys as atoms:

  1> Push = fun(Key, Value, Acc) -> [{binary_to_existing_atom(Key), Value} | Acc] end.
  2> json:decode(<<"{\"foo\": 1}">>, ok, #{object_push => Push}).
  {#{foo => 1},ok,<<>>}
Link to this function

decode_continue(Cont, Opaque)

View Source
-spec decode_continue(binary() | end_of_input, Opaque :: term()) ->
                   {Result :: dynamic(), Acc :: dynamic(), binary()} |
                   {continue, continuation_state()}.

Continue parsing a stream of bytes of a JSON value.

Similar to decode_start/3, if the function returns {continue, State} and there is no more data, use end_of_input instead of a binary.

  1> {continue, State} = json:decode_start(<<"{\"foo\":">>, ok, #{}).
  2> json:decode_continue(<<"1}">>, State).
  {#{foo => 1},ok,<<>>}
  1> {continue, State} = json:decode_start(<<"123">>, ok, #{}).
  2> json:decode_continue(end_of_input, State).
  {123,ok,<<>>}
Link to this function

decode_start(Binary, Acc, Decoders)

View Source
-spec decode_start(binary(), dynamic(), decoders()) ->
                {Result :: dynamic(), Acc :: dynamic(), binary()} |
                {continue, continuation_state()}.

Begin parsing a stream of bytes of a JSON value.

Similar to decode/3 but returns when a complete JSON value can be parsed or returns {continue, State} for incomplete data, the State can be fed to the decode_continue/2 function when more data is available.
-spec encode(encode_value()) -> iodata().

Generates JSON corresponding to Term.

Supports basic data mapping:

| Erlang | JSON | |------------------------|----------| | integer() \| float() | Number | | true \| false | Boolean | | null | Null | | binary() | String | | atom() | String | | list() | Array | | #{binary() => _} | Object | | #{atom() => _} | Object | | #{integer() => _} | Object |

This is equivalent to encode(Term, fun json:encode_value/2).

Examples

  1> iolist_to_binary(json:encode(#{foo => <<"bar">>})).
  <<"{\"foo\":\"bar\"}">>
-spec encode(dynamic(), encoder()) -> iodata().

Generates JSON corresponding to Term.

Can be customised with the Encoder callback. The callback will be recursively called for all the data to be encoded and is expected to return the corresponding encoded JSON as iodata.

Various encode_* functions in this module can be used to help in constructing such callbacks.

Examples

An encoder that uses a heuristic to differentiate object-like lists of key-value pairs from plain lists:

  1> encoder([{_, _} | _] = Value, Encode) -> json:encode_key_value_list(Value, Encode);
  2> encoder(Other, Encode) -> json:encode_value(Other, Encode).
  3> custom_encode(Value) -> json:encode(Value, fun(Value, Encode) -> encoder(Value, Encode) end).
  4> iolist_to_binary(custom_encode([{a, []}, {b, 1}])).
  <<"{\"a\":[],\"b\":1}">>
Link to this function

encode_atom(Other, Encode)

View Source
-spec encode_atom(atom(), encoder()) -> iodata().

Default encoder for atoms used by json:encode/1.

Encodes the atom null as JSON null, atoms true and false as JSON booleans, and everything else as JSON strings calling the Encode callback with the corresponding binary.
-spec encode_binary(binary()) -> iodata().

Default encoder for binaries as JSON strings used by json:encode/1.

Errors

- error(unexpected_end) if the binary contains incomplete UTF-8 sequences. - error({invalid_byte, Byte}) if the binary contains invalid UTF-8 sequences.
Link to this function

encode_binary_escape_all(Bin)

View Source
-spec encode_binary_escape_all(binary()) -> iodata().

Encoder for binaries as JSON strings producing pure-ASCII JSON.

For any non-ASCII unicode character, a corresponding \\uXXXX sequence is used.

Errors

- error(unexpected_end) if the binary contains incomplete UTF-8 sequences. - error({invalid_byte, Byte}) if the binary contains invalid UTF-8 sequences.
-spec encode_float(float()) -> iodata().
Default encoder for floats as JSON numbers used by json:encode/1.
-spec encode_integer(integer()) -> iodata().
Default encoder for integers as JSON numbers used by json:encode/1.
Link to this function

encode_key_value_list(List, Encode)

View Source
-spec encode_key_value_list([{term(), term()}], encoder()) -> iodata().

Encoder for lists of key-value pairs as JSON objects.

Accepts lists with atom, binary, integer, or float keys.
Link to this function

encode_key_value_list_checked(List, Encode)

View Source
-spec encode_key_value_list_checked([{term(), term()}], encoder()) -> iodata().

Encoder for lists of key-value pairs as JSON objects.

Accepts lists with atom, binary, integer, or float keys. Verifies that no duplicate keys will be produced in the resulting JSON object.

Errors

Raises error({duplicate_key, Key}) if there are duplicates.
Link to this function

encode_list(List, Encode)

View Source
-spec encode_list(list(), encoder()) -> iodata().
Default encoder for lists as JSON arrays used by json:encode/1.
-spec encode_map(encode_map(dynamic()), encoder()) -> iodata().

Default encoder for maps as JSON objects used by json:encode/1.

Accepts maps with atom, binary, integer, or float keys.
Link to this function

encode_map_checked(Map, Encode)

View Source
-spec encode_map_checked(map(), encoder()) -> iodata().

Encoder for maps as JSON objects.

Accepts maps with atom, binary, integer, or float keys. Verifies that no duplicate keys will be produced in the resulting JSON object.

Errors

Raises error({duplicate_key, Key}) if there are duplicates.
Link to this function

encode_value(Value, Encode)

View Source
-spec encode_value(dynamic(), encoder()) -> iodata().

Default encoder used by json:encode/1.

Recursively calls Encode on all the values in Value.