RequestSeal.Body (RequestSeal v0.2.0)

Copy Markdown View Source

Caller-owned body availability, without implicit reads or replayability.

new/1 requires :state: :retained requires binary :bytes; :streaming requires a caller-owned :source PID or reference; :unavailable and :consumed carry neither. Empty retained bytes are different from unavailable bytes. :ownership can only be :caller. :max_bytes bounds retained bytes (default 1,048,576; any nonnegative integer is allowed as the caller's retention policy). Unknown keys reject. Stream handles are opaque; construction/validation never invoke, enumerate, close, or claim to have consumed them.

Values are snapshots supplied by the caller, not a stream controller. A later snapshot must report consumption; copying a value does not make a stream replayable. A stream can remain unread after transport completes, so known trailers can coexist with :streaming. This module neither hashes content nor validates message framing. Inspection hides body bytes and handles.

iex> {:ok, body} = RequestSeal.Body.new(%{state: :retained, bytes: <<0, 255>>, max_bytes: 2})
iex> {body.state, body.bytes, body.ownership}
{:retained, <<0, 255>>, :caller}
iex> RequestSeal.Body.new(%{state: :streaming})
{:error, %RequestSeal.Message.Error{reason: :invalid_body}}

Summary

Functions

Construct an availability snapshot or return :invalid_body.

Validate a snapshot without touching the caller's body source.

Types

t()

@type t() :: %RequestSeal.Body{
  bytes: binary() | nil,
  max_bytes: non_neg_integer(),
  ownership: :caller,
  source: pid() | reference() | nil,
  state: :retained | :streaming | :unavailable | :consumed
}

Functions

new(attrs)

@spec new(map()) :: {:ok, t()} | {:error, RequestSeal.Message.Error.t()}

Construct an availability snapshot or return :invalid_body.

validate(body)

@spec validate(term()) :: :ok | {:error, RequestSeal.Message.Error.t()}

Validate a snapshot without touching the caller's body source.