Исходный код JSON
Кодирование и декодирование JSON.
Как кодировщик, так и декодер полностью соответствуют стандартам RFC 8259 и ECMA 404.
Кодирование
Встроенные структуры данных Elixir кодируются в JSON следующим образом:
| Elixir | JSON |
|---|---|
integer() | float() |
Число |
true | false |
Булево значение |
nil |
Null |
binary() |
Строка |
atom() |
Строка |
list() |
Массив |
%{binary() => _} |
Объект |
%{atom() => _} |
Объект |
%{integer() => _} |
Объект |
Вы также можете реализовать протокол JSON.Encoder для пользовательских структур данных.
Декодирование
Встроенные структуры данных Elixir декодируются из JSON следующим образом:
| JSON | Elixir |
|---|---|
| Число | integer() | float() |
| Булево значение | true | false |
| Null | nil |
| Строка | binary() |
| Объект | %{binary() => _} |
Сводка
Типы
Функции
- decode(binary)
Декодирует заданный JSON.
- decode(binary, acc, decoders)
Декодирует заданный JSON с заданными декодерами.
- decode!(binary)
Декодирует заданный JSON, но вызывает исключение в случае ошибок.
- encode!(term, encoder \\ &protocol_encode/2)
Кодирует заданный термин в JSON как двоичную строку.
- encode_to_iodata!(term, encoder \\ &protocol_encode/2)
Кодирует заданный термин в JSON как iodata.
- protocol_encode(value, encoder)
Это реализация кодирования по умолчанию, передаваемая в
encode!/1.
Типы
decode_error_reason()Исходный код
@type decode_error_reason() ::
{:unexpected_end, non_neg_integer()}
| {:invalid_byte, non_neg_integer(), byte()}
| {:unexpected_sequence, non_neg_integer(), binary()} encoder()Исходный код
@type encoder() :: (term(), encoder() -> iodata())
Функции
decode(binary)Исходный код
@spec decode(binary()) :: {:ok, term()} | {:error, decode_error_reason()} Декодирует заданный JSON.
Возвращает {:ok, decoded} или {:error, reason}.
Примеры
iex> JSON.decode("[null,123,\"string\",{\"key\":\"value\"}]")
{:ok, [nil, 123, "string", %{"key" => "value"}]}
Причины ошибок
Кортеж с ошибкой будет содержать одну из следующих причин.
-
{:unexpected_end, offset}еслиbinaryсодержит неполное значение JSON -
{:invalid_byte, offset, byte}еслиbinaryсодержит неожиданный байт или недопустимый байт UTF-8 -
{:unexpected_sequence, offset, bytes}еслиbinaryсодержит недопустимый UTF-8 escape
decode(binary, acc, decoders)Исходный код
@spec decode(binary(), term(), keyword()) ::
{term(), term(), binary()} | {:error, decode_error_reason()} Декодирует заданный JSON с заданными декодерами.
Возвращает {decoded, acc, rest} или {:error, reason}. См. decode/1 для причин ошибок.
Декодеры
Все декодеры необязательны. Если они не указаны, они будут использовать реализации, используемые функцией decode/1:
- для
array_start:fn _ -> [] end для
array_push:fn elem, acc -> [elem | acc] end- для
array_finish:fn acc, old_acc -> {Enum.reverse(acc), old_acc} end - для
object_start:fn _ -> [] end для
object_push:fn key, value, acc -> [{key, value} | acc] end- для
object_finish:fn acc, old_acc -> {Map.new(acc), old_acc} end - для
float:&String.to_float/1 - для
integer:&String.to_integer/1 - для
string:&Function.identity/1 - для
null: атомnil
Для потокового декодирования см. модуль :json в Erlang.
decode!(binary)Исходный код
@spec decode!(binary()) :: term()
Декодирует заданный JSON, но вызывает исключение в случае ошибок.
Возвращает декодированное содержимое. См. decode/1 для возможных ошибок.
Примеры
iex> JSON.decode!("[null,123,\"string\",{\"key\":\"value\"}]")
[nil, 123, "string", %{"key" => "value"}] encode!(term, encoder \\ &protocol_encode/2)Исходный код
@spec encode!(term(), encoder()) :: binary()
Кодирует заданный термин в JSON как двоичную строку.
Второй аргумент — функция, которая рекурсивно вызывается для кодирования термина.
IO и производительность
Если вам нужно закодировать данные для отправки по сети или записи в файловую систему, рассмотрите более эффективный метод encode_to_iodata!/2.
Примеры
iex> JSON.encode!([123, "string", %{key: "value"}])
"[123,\"string\",{\"key\":\"value\"}]" encode_to_iodata!(term, encoder \\ &protocol_encode/2)Исходный код
@spec encode_to_iodata!(term(), encoder()) :: iodata()
Кодирует заданный термин в JSON как iodata.
Это наиболее эффективный формат, если JSON будет использоваться для целей ввода-вывода.
Второй аргумент — функция, которая рекурсивно вызывается для кодирования термина.
Примеры
iex> data = JSON.encode_to_iodata!([123, "string", %{key: "value"}])
iex> IO.iodata_to_binary(data)
"[123,\"string\",{\"key\":\"value\"}]" protocol_encode(value, encoder)Исходный код
@spec protocol_encode(term(), encoder()) :: iodata()
Это реализация кодирования по умолчанию, передаваемая в encode!/1.
Эта функция обычно передаётся как второй аргумент к encode!/2 и encode_to_iodata!/2. Реализация по умолчанию — оптимизированная передача протоколу JSON.Encoder.
© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.18.1/JSON.html