Current section
Files
Jump to
Current section
Files
lib/jaxon.ex
defmodule Jaxon do
@moduledoc """
Main Jaxon module.
"""
defp do_decode(binary, offset, size, fun) do
part = :binary.part(binary, offset, min(size, byte_size(binary) - offset))
events =
if offset + size >= byte_size(binary) do
Jaxon.Parser.parse(part) ++ [:end_stream]
else
Jaxon.Parser.parse(part)
end
events
|> fun.()
|> case do
{:yield, tail, fun} ->
do_decode(
binary,
offset + size - byte_size(tail),
max(byte_size(tail) * 2, size),
fun
)
{:ok, result} ->
{:ok, result}
{:error, err} ->
{:error, err}
end
end
@doc """
Decode a string.
```elixir
iex> Jaxon.decode(~s({"jaxon":"rocks","array":[1,2]}))
{:ok, %{"array" => [1, 2], "jaxon" => "rocks"}}
```
"""
@spec decode(String.t()) :: {:ok, Jaxon.Decoder.json_term()} | {:error, %Jaxon.ParseError{}}
def decode(binary) do
do_decode(binary, 0, 80 * 1024, &Jaxon.Decoder.events_to_term/1)
end
@doc """
Decode a string, throws if there's an error.
```elixir
iex(1)> Jaxon.decode!(~s({"jaxon":"rocks","array":[1,2]}))
%{"array" => [1, 2], "jaxon" => "rocks"}
```
"""
@spec decode!(String.t()) :: Jaxon.Decoder.json_term() | no_return()
def(decode!(binary)) do
case decode(binary) do
{:ok, term} -> term
{:error, err} -> raise err
end
end
end