View Source JSON (Elixir v1.18.0)
JSON encoding and decoding.
Both encoder and decoder fully conform to RFC 8259 and ECMA 404 standards.
Encoding
Elixir built-in data structures are encoded to JSON as follows:
Elixir | JSON |
---|---|
integer() | float() | Number |
true | false | Boolean |
nil | Null |
binary() | String |
atom() | String |
list() | Array |
%{binary() => _} | Object |
%{atom() => _} | Object |
%{integer() => _} | Object |
You may also implement the JSON.Encoder
protocol for custom data structures.
Decoding
Elixir built-in data structures are decoded from JSON as follows:
JSON | Elixir |
---|---|
Number | integer() | float() |
Boolean | true | false |
Null | nil |
String | binary() |
Object | %{binary() => _} |
Summary
Types
@type decode_error_reason() :: {:unexpected_end, non_neg_integer()} | {:invalid_byte, non_neg_integer(), byte()} | {:unexpected_sequence, non_neg_integer(), binary()}
Functions
@spec decode(binary()) :: {:ok, term()} | {:error, decode_error_reason()}
Decodes the given JSON.
Returns {:ok, decoded}
or {:error, reason}
.
Examples
iex> JSON.decode("[null,123,\"string\",{\"key\":\"value\"}]")
{:ok, [nil, 123, "string", %{"key" => "value"}]}
Error reasons
The error tuple will have one of the following reasons.
{:unexpected_end, offset}
ifbinary
contains incomplete JSON value{:invalid_byte, offset, byte}
ifbinary
contains unexpected byte or invalid UTF-8 byte{:unexpected_sequence, offset, bytes}
ifbinary
contains invalid UTF-8 escape
@spec decode(binary(), term(), keyword()) :: {term(), term(), binary()} | {:error, decode_error_reason()}
Decodes the given JSON with the given decoders.
Returns {decoded, acc, rest}
or {:error, reason}
.
See decode/1
for the error reasons.
Decoders
All decoders are optional. If not provided, they will fall back to
implementations used by the decode/1
function:
- for
array_start
:fn _ -> [] end
for
array_push
:fn elem, acc -> [elem | acc] end
- for
array_finish
:fn acc, old_acc -> {Enum.reverse(acc), old_acc} end
- for
object_start
:fn _ -> [] end
for
object_push
:fn key, value, acc -> [{key, value} | acc] end
- for
object_finish
:fn acc, old_acc -> {Map.new(acc), old_acc} end
- for
float
:&String.to_float/1
- for
integer
:&String.to_integer/1
- for
string
:&Function.identity/1
- for
null
: the atomnil
For streaming decoding, see Erlang's :json
module.
Decodes the given JSON but raises an exception in case of errors.
Returns the decoded content. See decode/1
for possible errors.
Examples
iex> JSON.decode!("[null,123,\"string\",{\"key\":\"value\"}]")
[nil, 123, "string", %{"key" => "value"}]
Encodes the given term to JSON as a binary.
The second argument is a function that is recursively invoked to encode a term.
IO and performance
If you need to encode data to be sent over the network
or written to the filesystem, consider using the more
efficient encode_to_iodata!/2
.
Examples
iex> JSON.encode!([123, "string", %{key: "value"}])
"[123,\"string\",{\"key\":\"value\"}]"
Encodes the given term to JSON as an iodata.
This is the most efficient format if the JSON is going to be used for IO purposes.
The second argument is a function that is recursively invoked to encode a term.
Examples
iex> data = JSON.encode_to_iodata!([123, "string", %{key: "value"}])
iex> IO.iodata_to_binary(data)
"[123,\"string\",{\"key\":\"value\"}]"
This is the default encode implementation passed to encode!/1
.
This function is most typically passed as second argument to
encode!/2
and encode_to_iodata!/2
. The default implementation
is an optimized dispatch to the JSON.Encoder
protocol.