Packages

Ultra-fast JSON encoding/decoding for Elixir. A drop-in Jason replacement that's 2-3x faster with 2-4x less memory, plus key interning for up to 2x faster bulk decoding. Full RFC 8259 compliance and memory safety. Purpose-built Rust NIFs, no serde.

Current section

Files

Jump to
rustyjson lib fragment.ex
Raw

lib/fragment.ex

defmodule RustyJson.Fragment do
@moduledoc """
Represents pre-encoded JSON that should be injected directly into output.
## Usage
# Pre-encode some JSON
fragment = RustyJson.Fragment.new(~s({"already": "encoded"}))
# Include in a larger structure
RustyJson.encode!(%{data: fragment, extra: "field"})
# => {"data":{"already":"encoded"},"extra":"field"}
"""
@type t :: %__MODULE__{encode: iodata() | (term() -> iodata())}
defstruct [:encode]
@doc """
Creates a new fragment from pre-encoded JSON.
"""
@spec new(iodata()) :: t()
def new(data) when is_binary(data) or is_list(data) do
%__MODULE__{encode: data}
end
@spec new((term() -> iodata())) :: t()
def new(encode) when is_function(encode, 1) do
%__MODULE__{encode: encode}
end
@doc """
Creates a validated fragment, ensuring the input is valid JSON.
Raises an error if the input is not valid JSON.
"""
@spec new!(iodata()) :: t()
def new!(data) do
_ = RustyJson.decode!(IO.iodata_to_binary(data))
%__MODULE__{encode: data}
end
end
defimpl RustyJson.Encoder, for: RustyJson.Fragment do
def encode(%RustyJson.Fragment{encode: encode} = fragment) when is_function(encode, 1) do
%{fragment | encode: encode.(nil)}
end
def encode(%RustyJson.Fragment{} = fragment), do: fragment
end