Current section
Files
Jump to
Current section
Files
lib/jaxon.ex
defmodule Jaxon do
@moduledoc ~S"""
## Example
Create a new decoder and add your JSON data:
```
decoder =
Jaxon.make_decoder()
|> Jaxon.update_decoder("{\"jaxon\":\"rocks\",\"array\":[1,2]}")
```
Call `decode/1` on the decoder to consume the events one by one:
```
iex> decoder = Jaxon.make_decoder() |> Jaxon.update_decoder("{\"jaxon\":\"rocks\",\"array\":[1,2]}")
iex> Jaxon.decode(decoder)
:start_object
```
Or call `consume/1` to read all the events in a list:
```
iex> decoder = Jaxon.make_decoder() |> Jaxon.update_decoder("{\"jaxon\":\"rocks\",\"array\":[1,2]}")
iex> Jaxon.consume(decoder)
[
:start_object,
{:key, "jaxon"},
{:string, "rocks"},
{:key, "array"},
:start_array,
{:integer, 1},
{:integer, 2},
:end_array,
:end_object,
:end
]
```
"""
@type event ::
:start_object
| :end_object
| :start_array
| :end_array
| {:key, binary}
| {:string, binary}
| {:integer, integer}
| {:decimal, float}
| {:boolean, boolean}
| nil
| {:incomplete, binary}
| :end
| :error
@type decoder :: reference()
@on_load :load_nifs
def load_nifs do
nif_filename =
:jaxon
|> Application.app_dir("priv/decoder")
|> to_charlist
:erlang.load_nif(nif_filename, [
:start_object,
:end_object,
:start_array,
:end_array,
:key,
:colon,
:comma,
:string,
:integer,
:boolean,
nil,
:error,
:incomplete,
:syntax_error,
:end
])
end
@doc ~S"""
Get a single event from the decoder, must call `update_decoder/2` with your data beforehand.
## Example
iex> Jaxon.make_decoder() |> Jaxon.update_decoder("{\"jaxon\":\"rocks\"}") |> Jaxon.decode()
:start_object
"""
@spec decode(decoder) :: event
def decode(_) do
raise "NIF not compiled"
end
@spec update_decoder(decoder, binary) :: decoder
def update_decoder(_, _) do
raise "NIF not compiled"
end
@spec make_decoder() :: decoder
def make_decoder() do
raise "NIF not compiled"
end
@doc ~S"""
Helper function that calls `decode/1` until there are no more events.
## Example
iex> Jaxon.make_decoder() |> Jaxon.update_decoder("{\"jaxon\":\"rocks\"}") |> Jaxon.consume()
[:start_object, {:key, "jaxon"}, {:string, "rocks"}, :end_object, :end]
"""
@spec consume(decoder) :: [event]
def consume(decoder) do
case Jaxon.decode(decoder) do
event = {:incomplete, _} ->
[event]
event when event in [:end, :error, :ok] ->
[event]
event ->
[event | consume(decoder)]
end
end
end