View Source Exneus (Exneus v0.1.0)
An incredibly flexible and performant JSON parser, generator and formatter for Elixir.
Summary
Functions
Decodes a binary JSON into a term.
Continue parsing a stream of bytes of a JSON value.
End parsing a stream of bytes of a JSON value.
Begin parsing a stream of bytes of a JSON value.
Encodes a term into a binary JSON.
Encode a term into an iodata JSON.
Formats a binary JSON.
Formats a binary JSON.
Minifies a binary JSON.
Minifies a binary JSON.
Types
@type decode_options() :: %{ optional(:codecs) => [:euneus_decoder.codec()], optional(:null) => term(), optional(:binary_to_float) => :json.from_binary_fun(), optional(:binary_to_integer) => :json.from_binary_fun(), optional(:array_start) => :json.array_start_fun(), optional(:array_push) => :json.array_push_fun(), optional(:array_finish) => :ordered | :reversed | :json.array_finish_fun(), optional(:object_start) => :json.object_start_fun(), optional(:object_keys) => :binary | :copy | :atom | :existing_atom | :json.from_binary_fun(), optional(:object_push) => :json.object_push_fun(), optional(:object_finish) => :map | :keyword_list | :reversed_keyword_list | :json.object_finish_fun() }
@type encode_options() :: %{ optional(:codecs) => [:euneus_encoder.codec()], optional(:codec_callback) => :euneus_encoder.codec_callback(), optional(:nulls) => [term()], optional(:skip_values) => [term()], optional(:key_to_binary) => (term() -> binary()), optional(:sort_keys) => boolean(), optional(:keyword_lists) => boolean() | {true, is_keyword_list()}, optional(:escape) => (binary() -> iodata()), optional(:encode_integer) => :euneus_encoder.encode(integer()), optional(:encode_float) => :euneus_encoder.encode(float()), optional(:encode_atom) => :euneus_encoder.encode(atom()), optional(:encode_list) => :euneus_encoder.encode(list()), optional(:encode_map) => :euneus_encoder.encode(map()), optional(:encode_tuple) => :euneus_encoder.encode(tuple()), optional(:encode_pid) => :euneus_encoder.encode(pid()), optional(:encode_port) => :euneus_encoder.encode(port()), optional(:encode_reference) => :euneus_encoder.encode(reference()), optional(:encode_term) => :euneus_encoder.encode(term()) }
@type is_keyword_list() :: :euneus_encoder.is_proplist()
Functions
@spec decode!(json, options) :: term() when json: binary(), options: decode_options()
Decodes a binary JSON into a term.
Example
iex> Exneus.decode!("\"foo\"")
"foo"
Option details
codecs
- Transforms a JSON binary value into an Erlang term. By returning:next
, the next codec will be called, or by returning{:halt, term :: term()}
, the term is returned as the value.You can use the built-in codecs or your own. Please see the
:euneus_decoder.codec/0
type for details.Default is
[]
.Built-in codecs:
timestamp
- Transforms an ISO 8601 string with milliseconds into an:erlang.timestamp/0
.Example:
iex> Exneus.decode!("\"1970-01-01T00:00:00.000Z\"", %{codecs: [:timestamp]}) {0, 0, 0}
datetime
- Transforms an ISO 8601 string into a:calendar.datetime/0
.Example:
iex> Exneus.decode!("\"1970-01-01T00:00:00Z\"", %{codecs: [:datetime]}) {{1970, 01, 01},{00, 00, 00}}
ipv4
- Transforms a JSON string into an:inet.ip4_address/0
.Example:
iex> Exneus.decode!("\"127.0.0.1\"", %{codecs: [:ipv4]}) {127, 0, 0, 1}
ipv6
- Transforms a JSON string into an:inet.ip6_address/0
.Example:
iex> Exneus.decode!("\"::\"", %{codecs: [:ipv6]}) {0, 0, 0, 0, 0, 0, 0, 0} iex> Exneus.decode!("\"::1\"", %{codecs: [:ipv6]}) {0, 0, 0, 0, 0, 0, 0, 1} iex> Exneus.decode!("\"::192.168.42.2\"", %{codecs: [:ipv6]}) {0, 0, 0, 0, 0, 0, 49320, 10754} iex> Exneus.decode!("\"::ffff:192.168.42.2\"", %{codecs: [:ipv6]}) {0, 0, 0, 0, 0, 65535, 49320, 10754} iex> Exneus.decode!("\"3ffe:b80:1f8d:2:204:acff:fe17:bf38\"", %{codecs: [:ipv6]}) {16382, 2944, 8077, 2, 516, 44287, 65047, 48952} iex> Exneus.decode!("\"fe80::204:acff:fe17:bf38\"", %{codecs: [:ipv6]}) {65152, 0, 0, 0, 516, 44287, 65047, 48952}
pid
- Transforms a JSON string into an:erlang.pid/0
.Example:
iex> Exneus.decode!("\"<0.92.0>\"", %{codecs: [:pid]}) ...> == :erlang.list_to_pid(~c"<0.92.0>") true
port
- Transforms a JSON string into an:erlang.port/0
.Example:
iex> Exneus.decode!("\"#Port<0.1>\"", %{codecs: [:port]}) ...> == :erlang.list_to_port(~c"#Port<0.1>") true
reference
- Transforms a JSON string into an:erlang.reference/0
.Example:
iex> Exneus.decode!("\"#Ref<0.314572725.1088159747.110918>\"", %{codecs: [:reference]}) ...> == :erlang.list_to_ref(~c"#Ref<0.314572725.1088159747.110918>") true
Custom codec example:
iex> Exneus.decode!("\"foo\"", %{codecs: [fn ("foo") -> {:halt, :foo} end]}) :foo
null
- Defines which term should be considered null.Default is
nil
.Example:
iex> Exneus.decode!("null", %{null: :null}) :null
binary_to_float
- Overrides the default binary to float conversion.binary_to_integer
- Overrides the default binary to integer conversion..array_start
- Overrides the:json.array_start_fun/0
callback.array_push
- Overrides the:json.array_push_fun/0
callback.array_finish
- Overrides the:json.array_finish_fun/0
callback.In addition to the custom function, there are:
ordered
- Returns the array in the same order as the JSON.That's the slower option.
Example:
iex> Exneus.decode!("[1,2,3]", %{array_finish: :ordered}) [1,2,3]
reversed
- Returns the array in a reversed order.That's the faster option.
Example:
iex> Exneus.decode!("[1,2,3]", %{array_finish: :reversed}) [3,2,1]
Default is
ordered
.object_start
- Overrides the:json.object_start_fun/0
callback.object_keys
- Transforms JSON objects key into Erlang term.In addition to the custom function, there are:
binary
- Returns the key as:erlang.binary/0
.copy
- Copies the key via:binary.copy/1
returning it as:erlang.binary/0
.atom
- Returns the key as:erlang.atom/0
via:erlang.binary_to_atom/2
.existing_atom
- Returns the key as:erlang.atom/0
via:erlang.binary_to_existing_atom/2
.
Default is
binary
.object_push
- Overrides the:json.object_push_fun/0
callback.object_finish
- Overrides the:json.object_finish_fun/0
callback.In addition to the custom function, there are:
map
- Returns the object as a:erlang.map/0
.That's the slower option.
Example:
iex> Exneus.decode!( ...> "{\"a\":\"a\",\"b\":\"b\",\"c\":\"c\"}", ...> %{object_finish: :map} ...> ) %{<<"a">> => <<"a">>,<<"b">> => <<"b">>,<<"c">> => <<"c">>}
keyword_list
- Returns the object as an orderedkeyword/0
.Example:
iex> Exneus.decode!( ...> "{\"a\":\"a\",\"b\":\"b\",\"c\":\"c\"}", ...> %{object_finish: :keyword_list} ...> ) [{"a", "a"},{"b", "b"},{"c", "c"}]
reversed_keyword_list
- Returns the object as a reversedkeyword/0
.That's the faster option.
Example:
iex> Exneus.decode!( ...> "{\"a\":\"a\",\"b\":\"b\",\"c\":\"c\"}", ...> %{object_finish: :reversed_keyword_list} ...> ) [{"c", "c"},{"b", "b"},{"a", "a"}]
Default is
map
.
@spec decode_stream_continue!(json, state) :: result when json: binary() | :end_of_input, state: :euneus_decoder.stream_state(), result: :euneus_decoder.stream_result()
Continue parsing a stream of bytes of a JSON value.
Example
iex> {:continue, state} = Exneus.decode_stream_start!("{\"foo\":")
iex> Exneus.decode_stream_continue!("1}", state)
{:end_of_input, %{"foo" => 1}}
@spec decode_stream_end!(state) :: result when state: :euneus_decoder.stream_state(), result: {:end_of_input, term()}
End parsing a stream of bytes of a JSON value.
Example
iex> {:continue, state} = Exneus.decode_stream_start!("123")
iex> Exneus.decode_stream_end!(state)
{:end_of_input, 123}
@spec decode_stream_start!(json, options) :: result when json: binary(), options: :euneus_decoder.options(), result: :euneus_decoder.stream_result()
Begin parsing a stream of bytes of a JSON value.
@spec encode!(term(), encode_options()) :: iodata()
Encodes a term into a binary JSON.
Example
iex> Exneus.encode!(:foo)
"\"foo\""
Option details
Note
For better visualization and understanding, all options examples use
Exneus.encode!/2
, which returns a binary.
codecs
- Transforms tuples into any other Erlang term that will be encoded again into a JSON value. By returning:next
, the next codec will be called, or by returning{:halt, term :: term()}
, the term will be encoded again.You can use the built-in codecs or your own. Please see the
:euneus_encoder.codec/0
type for details.Default is
[]
.Built-in codecs:
timestamp
- Transforms an:erlang.timestamp/0
into an ISO 8601 string with milliseconds.Example:
iex> Exneus.encode!({0, 0, 0}, %{codecs: [:timestamp]}) "\"1970-01-01T00:00:00.000Z\""
datetime
- Transforms a:calendar.datetime/0
into an ISO 8601 string.Example:
iex> Exneus.encode!({{1970, 01, 01}, {00, 00, 00}}, %{codecs: [:datetime]}) "\"1970-01-01T00:00:00Z\""
ipv4
- Transforms an:inet.ip4_address/0
into a JSON string.Example:
iex> Exneus.encode!({127, 0, 0, 1}, %{codecs: [:ipv4]}) "\"127.0.0.1\""
ipv6
- Transforms an:inet.ip6_address/0
into a JSON string.Example:
iex> Exneus.encode!({0, 0, 0, 0, 0, 0, 0, 0}, %{codecs: [:ipv6]}) "\"::\"" iex> Exneus.encode!({0, 0, 0, 0, 0, 0, 0, 1}, %{codecs: [:ipv6]}) "\"::1\"" iex> Exneus.encode!({0, 0, 0, 0, 0, 0, 49320, 10754}, %{codecs: [:ipv6]}) "\"::192.168.42.2\"" iex> Exneus.encode!({0, 0, 0, 0, 0, 65535, 49320, 10754}, %{codecs: [:ipv6]}) "\"::ffff:192.168.42.2\"" iex> Exneus.encode!({16382, 2944, 8077, 2, 516, 44287, 65047, 48952}, %{codecs: [:ipv6]}) "\"3ffe:b80:1f8d:2:204:acff:fe17:bf38\"" iex> Exneus.encode!({65152, 0, 0, 0, 516, 44287, 65047, 48952}, %{codecs: [:ipv6]}) "\"fe80::204:acff:fe17:bf38\""
records
- Transforms records into JSON objects.Example:
iex> Exneus.encode!( ...> # Same as `Record.defrecord(:foo, :bar, :baz)` ...> {:foo, :bar, :baz}, ...> %{codecs: [{:records, %{ ...> # Use `Record.extract/2` to extract those record informations ...> foo: {[:bar, :baz], 3} ...> }}]} ...> ) if String.to_integer(System.otp_release) >= 26 do "{\"bar\":\"bar\",\"baz\":\"baz\"}" else "{\"baz\":\"baz\",\"bar\":\"bar\"}" end
Custom codec example:
iex> Exneus.encode!({:foo}, %{codecs: [fn ({:foo}) -> {:halt, :foo} end]}) "\"foo\""
codec_callback
- Overrides the default codec resolver.Default is
euneus_encoder.codec_callback/2
.nulls
- Defines which values should be encoded as null.Default is
[nil]
.Example:
iex> Exneus.encode!([:null, nil, :foo], %{nulls: [:null, nil]}) "[null,null,\"foo\"]"
skip_values
- Defines which map values should be ignored. This option permits achieves the same behavior as Javascript, which ignores undefined values of objects.Default is
[]
.Example:
iex> Exneus.encode!( ...> %{foo: :bar, bar: :undefined}, ...> %{skip_values: [:undefined]} ...> ) "{\"foo\":\"bar\"}"
key_to_binary
- Overrides the default conversion of map keys to a string.Default is
:euneus_encoder.key_to_binary/1
.sort_keys
- Defines if the object keys should be sorted.Default is
false
.Example:
iex> Exneus.encode!(%{c: :c, a: :a, b: :b}, %{sort_keys: true}) "{\"a\":\"a\",\"b\":\"b\",\"c\":\"c\"}"
keyword_lists
- If true, converts keyword_lists into objects.Default is
false
.Example:
iex> Exneus.encode!([:baz, foo: :bar], %{keyword_lists: true}) "{\"foo\":\"bar\",\"baz\":true}" iex> Exneus.encode!( ...> [foo: :bar, baz: true], ...> # Overrides the default is keyword list check: ...> %{keyword_lists: {true, fn ([{_, _} | _]) -> true end}} ...> ) "{\"foo\":\"bar\",\"baz\":true}"
escape
- Overrides the default string escaping.Default is
:euneus_encoder.escape/1
.encode_integer
- Overrides the default integer encoder.Default is
:euneus_encoder.encode_integer/2
.encode_float
- Overrides the default float encoder.Default is
:euneus_encoder.encode_float/2
.encode_atom
- Overrides the default atom encoder.Default is
:euneus_encoder.encode_atom/2
.encode_list
- Overrides the default list encoder.Default is
:euneus_encoder.encode_list/2
.encode_map
- Overrides the default map encoder.Default is the private function Exneus.encode_map/2.
encode_tuple
- Overrides the default tuple encoder.Default is
:euneus_encoder.encode_tuple/2
, which raises:unsupported_tuple
error.encode_pid
- Overrides the default pid encoder.Default is
:euneus_encoder.encode_pid/2
, which raises:unsupported_pid
error.encode_port
- Overrides the default port encoder.Default is
:euneus_encoder.encode_port/2
, which raises:unsupported_port
error.encode_reference
- Overrides the default reference encoder.Default is
:euneus_encoder.encode_reference/2
, which raises:unsupported_reference
error.encode_term
- Overrides the default encoder for unsupported terms, like functions.Default is
:euneus_encoder.encode_term/2
, which raises:unsupported_term
error.
@spec encode_to_iodata!(term(), encode_options()) :: iodata()
Encode a term into an iodata JSON.
Example
iex> Exneus.encode_to_iodata!(:foo)
[?", "foo", ?"]
@spec format(json, options) :: binary() when json: binary(), options: :euneus_formatter.options()
Formats a binary JSON.
Example
iex> opts = %{
...> indent_type: :tabs,
...> indent_width: 1,
...> spaced_values: true,
...> crlf: :n
...> }
%{crlf: :n, indent_type: :tabs, indent_width: 1, spaced_values: true}
iex> Exneus.format(" \n{\"foo\" : [ true , \n null ] \n } ", opts)
"{\n\t\"foo\": [\n\t\ttrue,\n\t\tnull\n\t]\n}"
Option details
Note
There is no default for any option, all are required.
indent_type
- Indent usingtabs
orspaces
.tabs
- The indent char will be?\t
.spaces
- The indent char will be?\s
.
indent_width
- Theindent_type
will be copied N times based on it.spaced_values
- Defines if keys and values of objects should be spaced by one?\s
char.crlf
- Defines the Carriage Return/Line Feed.r
- The CRLF will be"\r"
.n
- The CRLF will be"\n"
.rn
- The CRLF will be"\r\n"
.none
- The CRLF will be""
.
@spec format_to_iodata(json, options) :: iodata() when json: binary(), options: :euneus_formatter.options()
Formats a binary JSON.
Minifies a binary JSON.
Example
iex> Exneus.minify(" \n{\"foo\" : [ true , \n null ] \n } ")
"{\"foo\":[true,null]}"
Minifies a binary JSON.