defmodule ForkPoison do
readme_path = [__DIR__, "..", "README.md"] |> Path.join() |> Path.expand()
@external_resource readme_path
@moduledoc readme_path |> File.read!() |> String.trim()
alias ForkPoison.{Decode, DecodeError, Decoder}
alias ForkPoison.{EncodeError, Encoder}
alias ForkPoison.{ParseError, Parser}
@doc """
Encode a value to JSON IO data.
iex> ForkPoison.encode_to_iodata([1, 2, 3])
{:ok, [91, ["1", 44, "2", 44, "3"], 93]}
iex> ForkPoison.encode_to_iodata({})
{:error, %ForkPoison.EncodeError{message: nil, value: {}}}
"""
@spec encode_to_iodata(Encoder.t()) :: {:ok, iodata} | {:error, EncodeError.t()}
@spec encode_to_iodata(Encoder.t(), Encoder.options() | [Encoder.option()]) ::
{:ok, iodata} | {:error, EncodeError.t()}
def encode_to_iodata(value, options \\ %{}) do
{:ok, encode_to_iodata!(value, options)}
rescue
exception in [EncodeError] ->
{:error, exception}
end
@doc """
Encode a value to JSON IO data. Raises an exception on error.
iex> ForkPoison.encode_to_iodata!([1, 2, 3])
[91, ["1", 44, "2", 44, "3"], 93]
iex> ForkPoison.encode_to_iodata!({})
** (ForkPoison.EncodeError) unable to encode value: {}
"""
@spec encode_to_iodata!(Encoder.t()) :: iodata
@spec encode_to_iodata!(Encoder.t(), Encoder.options() | [Encoder.option()]) :: iodata
def encode_to_iodata!(value, options \\ %{})
def encode_to_iodata!(value, options) when is_list(options) do
encode_to_iodata!(value, Map.new(options))
end
def encode_to_iodata!(value, options) do
Encoder.encode(value, options)
end
@doc """
Encode a value to JSON.
iex> ForkPoison.encode([1, 2, 3])
{:ok, "[1,2,3]"}
iex> ForkPoison.encode({})
{:error, %ForkPoison.EncodeError{message: nil, value: {}}}
"""
@spec encode(Encoder.t()) :: {:ok, iodata} | {:error, EncodeError.t()}
@spec encode(Encoder.t(), Encoder.options() | [Encoder.option()]) ::
{:ok, iodata} | {:error, EncodeError.t()}
def encode(value, options \\ %{}) do
{:ok, encode!(value, options)}
rescue
exception in [EncodeError] ->
{:error, exception}
end
@doc """
Encode a value to JSON. Raises an exception on error.
iex> ForkPoison.encode!([1, 2, 3])
"[1,2,3]"
iex> ForkPoison.encode!({})
** (ForkPoison.EncodeError) unable to encode value: {}
"""
@spec encode!(Encoder.t()) :: binary
@spec encode!(Encoder.t(), Encoder.options() | [Encoder.option()]) :: binary
def encode!(value, options \\ %{})
def encode!(value, options) when is_list(options) do
encode!(value, Map.new(options))
end
def encode!(value, options) do
value |> encode_to_iodata!(options) |> IO.iodata_to_binary()
end
@doc """
Decode JSON to a value.
iex> ForkPoison.decode("[1,2,3]")
{:ok, [1, 2, 3]}
iex> ForkPoison.decode("[")
{:error, %ForkPoison.ParseError{data: "[", skip: 1, value: nil}}
"""
@spec decode(iodata) :: {:ok, Parser.t()} | {:error, ParseError.t() | DecodeError.t()}
@spec decode(iodata, Decoder.options() | [Decoder.option()]) ::
{:ok, Decoder.t()} | {:error, ParseError.t() | DecodeError.t()}
def decode(iodata, options \\ %{}) do
{:ok, decode!(iodata, options)}
rescue
exception in [ParseError, DecodeError] ->
{:error, exception}
end
@doc """
Decode JSON to a value. Raises an exception on error.
iex> ForkPoison.decode!("[1,2,3]")
[1, 2, 3]
iex> ForkPoison.decode!("[")
** (ForkPoison.ParseError) unexpected end of input at position 1
"""
@spec decode!(iodata) :: Parser.t()
@spec decode!(iodata, Decoder.options() | [Decoder.option()]) :: Decoder.t()
def decode!(value, options \\ %{})
def decode!(value, options) when is_list(options) do
decode!(value, Map.new(options))
end
def decode!(value, %{as: as} = options) when as != nil do
value
|> Parser.parse!(options)
|> Decode.transform(options)
end
def decode!(value, options) do
Parser.parse!(value, options)
end
end