Skip to main content

Frame

Enum Frame 

Source
pub enum Frame {
    Handshake {
        version: ProtocolVersion,
    },
    HandshakeAck {
        version: ProtocolVersion,
    },
    Request {
        id: OperationId,
        ops: String,
        deadline_ms: Option<u64>,
        namespace: Option<String>,
        actor_id: Option<String>,
        visible_namespaces: Option<Vec<String>>,
    },
    Response {
        id: OperationId,
        result: Value,
    },
    Error {
        id: Option<OperationId>,
        code: WireErrorCode,
        message: String,
        unrecognized_code: Option<String>,
    },
    Cancel {
        id: OperationId,
    },
    Subscribe {
        id: OperationId,
        topic: String,
        resume_cursor: Option<Cursor>,
    },
    SubscribeAck {
        id: OperationId,
        topic: String,
        start_cursor: Cursor,
    },
    Unsubscribe {
        id: OperationId,
        topic: String,
    },
    UnsubscribeAck {
        id: OperationId,
        topic: String,
    },
    Event {
        topic: String,
        cursor: Cursor,
        occurred_at: String,
        payload: Value,
    },
}
Expand description

One application frame.

Every variant corresponds to exactly one entry in FRAME_KINDS and is carried on the wire as a JSON object with a "kind" discriminant field holding that variant’s snake_case name, followed by the variant’s own fields flattened into the same object. This is the wire framing’s internally tagged encoding; see the crate documentation for a worked example of the exact bytes.

The set is closed within a protocol version (ADR-137, “Decision”): a decoder that encounters a "kind" value outside FRAME_KINDS must reject the frame (crate::codec::CodecError::UnknownFrameKind), never skip or ignore it.

Serde is implemented by hand (rather than #[serde(tag = "kind")]) so the decode path can enforce the closed grammar ADR-137 requires: the codec checks the "kind" discriminant against FRAME_KINDS itself, then hands the payload to the matching kind’s payload struct (HandshakePayload, RequestPayload, …), every one of which carries #[serde(deny_unknown_fields)]. A payload with any field its kind does not declare is therefore rejected — never silently ignored — and a missing or non-string "kind" is rejected before any kind is matched. The visitor likewise enforces the ADR-137 id/scope rule for error frames and captures the unknown-code fallback’s raw string (Frame::Error’s unrecognized_code), so a DIRECT serde decode of Frame — not just the codec — can never represent an inconsistent error frame. Encoding writes "kind" first, then the kind’s fields in declaration order, skipping absent optional fields; this is the exact byte layout the golden fixtures pin.

Variants§

§

Handshake

The first application frame on every connection. Names the protocol version the client supports.

Fields

§version: ProtocolVersion

The protocol version the client wants to speak.

§

HandshakeAck

The server’s acceptance of a Frame::Handshake, naming the accepted protocol version.

Fields

§version: ProtocolVersion

The protocol version the connection now speaks.

§

Request

A caller-issued operation: a DSL batch or chain (ADR-016) to execute.

Fields

§id: OperationId

Caller-generated, connection-unique operation id.

§ops: String

The request DSL string (ADR-016’s function-call or JSON form).

§deadline_ms: Option<u64>

Optional deadline in milliseconds, measured from server receipt of this frame against the server’s monotonic clock. Scopes the entire request frame (the whole DSL batch or chain).

§namespace: Option<String>

Frame-level namespace override. Legal only on transports that accept caller-supplied identity context; a mapped transport (ADR-137’s TCP transport) rejects any request carrying this with crate::error::WireErrorCode::ContextRejected.

§actor_id: Option<String>

Frame-level actor override; see namespace above.

§visible_namespaces: Option<Vec<String>>

Frame-level visible-namespace-set override; see namespace above.

§

Response

The successful terminal frame for a request.

Fields

§id: OperationId

Echoes the originating request’s operation id.

§result: Value

The verb-dispatch result, exactly as ADR-016’s request verb surface returns it (an aggregate {ok, tool, result} / {ok, summary, ...} payload). Opaque to this crate.

§

Error

A wire-level failure terminal frame.

Fields

§id: Option<OperationId>

The operation id this error terminates, for a request-scoped error. None for a connection-terminal error, which carries no operation id (ADR-137, “Operation correlation”).

§code: WireErrorCode

The wire error code.

§message: String

A human-readable detail message. Not part of the closed contract — callers must branch on code, never on this string.

§unrecognized_code: Option<String>

The raw code string when the wire carried a code OUTSIDE the closed set (crate::error::WIRE_ERROR_CODES) and serde’s #[serde(other)] fallback mapped it to crate::error::WireErrorCode::Internal; None for every recognized code, and for every frame this crate produced by encoding or by in-memory construction. Diagnostic only: it is never serialized, and only DECODE paths fill it — this type’s serde visitor, whether driven by the codec’s decode_payload or by a direct serde decode. A frame carrying it is a decoded fallback and cannot be re-encoded by this relay: the encode path rejects it (crate::codec::CodecError::FallbackFrameNotEncodable) rather than emit internal and silently discard the newer code. The connection remains healthy; only this relay attempt failed. If it has no operation id, a consumer should surface it as a connection-level diagnostic rather than guess which request to fail.

§

Cancel

Asks the server to terminate an in-flight request.

Fields

§id: OperationId

The request operation id to cancel. A cancel naming a subscribe/unsubscribe id, or an unknown or already-terminal request id, is a no-op.

§

Subscribe

Opens delivery for one topic on the connection.

Fields

§id: OperationId

Caller-generated, connection-unique operation id.

§topic: String

The topic to subscribe to, <domain>.<event>.

§resume_cursor: Option<Cursor>

Resume position. Absent starts delivery at new events only; present replays every retained event with a cursor greater than this value before delivering new events.

§

SubscribeAck

The successful terminal frame for a subscribe.

Fields

§id: OperationId

Echoes the originating subscribe’s operation id.

§topic: String

The subscribed topic.

§start_cursor: Cursor

The cursor position delivery begins after.

§

Unsubscribe

Ends delivery for one topic on the connection.

Fields

§id: OperationId

Caller-generated, connection-unique operation id.

§topic: String

The topic to unsubscribe from. Naming a topic with no active subscription is an idempotent no-op.

§

UnsubscribeAck

The terminal frame for an unsubscribe.

Fields

§id: OperationId

Echoes the originating unsubscribe’s operation id.

§topic: String

The unsubscribed topic.

§

Event

A server-pushed state-change delivery for a subscribed topic.

Carries no operation id; correlated by topic and ordered by cursor instead.

Fields

§topic: String

The topic this event belongs to.

§cursor: Cursor

Server-assigned, per-topic, strictly increasing resumption cursor.

§occurred_at: String

Server-assigned event time, RFC 3339.

§payload: Value

Topic-specific payload. Field-by-field shape is owned by the per-topic catalog (ADR-137, “Implementation-phase deliverables”), not by this crate.

Implementations§

Source§

impl Frame

Source

pub const fn kind(&self) -> &'static str

The snake_case frame-kind name of this frame, matching its "kind" discriminant on the wire.

Trait Implementations§

Source§

impl Clone for Frame

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Frame

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Frame

The decode half of the closed grammar; see the type-level docs and the crate documentation’s “Strict field rejection” section. The codec’s decode_payload drives this via serde_json::from_value::<Frame> after its own closed-set "kind" check (which produces the finer-grained crate::codec::CodecError::UnknownFrameKind).

The visitor enforces every decode-time rule that only needs the fields of one frame, so a DIRECT serde decode of Frame (e.g. serde_json::from_str::<Frame>) agrees with the codec path:

  • the ADR-137 id/scope pairing for error frames — a connection-terminal code must carry no operation id, and a request-terminal code must echo the one it terminates (crate::codec::CodecError::InconsistentErrorScope is the codec’s typed form of this rejection; a direct serde decode reports the same rule through its deserializer’s error type); and
  • the unknown-code fallback diagnostic: an error frame whose wire code is outside the closed set (crate::error::WIRE_ERROR_CODES) carries the raw string in unrecognized_code.

The one guarantee only the codec path provides is the finer-grained crate::codec::CodecError::UnknownFrameKind classification for a "kind" outside FRAME_KINDS; this visitor rejects unknown kinds too, with the deserializer’s own error type.

Source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Frame

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for Frame

Serialize one frame as its wire object: "kind" first, then the kind’s fields in declaration order, absent optional fields skipped. The byte layout is pinned by the golden fixtures in tests/fixtures/*.hex.

Source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Frame

Auto Trait Implementations§

§

impl Freeze for Frame

§

impl RefUnwindSafe for Frame

§

impl Send for Frame

§

impl Sync for Frame

§

impl Unpin for Frame

§

impl UnsafeUnpin for Frame

§

impl UnwindSafe for Frame

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.