Skip to main content

SseEvent

Struct SseEvent 

Source
pub struct SseEvent { /* private fields */ }
Expand description

One text/event-stream frame.

id is optional because the format says so: a frame without an id: is legal SSE and dispatches normally, it simply does not move the client’s resume cursor. That is the shape a keep-alive-adjacent event takes, and an encoder that always wrote an id would either invent a cursor position that never existed or refuse to emit the frame at all.

name is optional for the same reason, and for a sharper one: Streamable HTTP never sets it — every frame on that transport is a message and the name carries nothing. The 2024-11-05 transport names every frame, and a client that dispatches on the name is the only way to tell an endpoint frame (where to POST) from a message frame (a JSON-RPC payload). A codec that dropped the name would parse a legacy stream perfectly and hand the client two indistinguishable event kinds.

A frame with no data does not exist as a value: the standard dispatches nothing for such a block, so decode reports SseError::NoData and dispatch reports None.

Implementations§

Source§

impl SseEvent

Source

pub const fn new(id: EventId, data: String) -> Self

A frame with a resume cursor.

Source

pub const fn without_id(data: String) -> Self

A frame with no resume cursor, which leaves the client’s where it was.

Source

pub const fn named(name: EventName, data: String) -> Self

A named frame, for the transports that dispatch on the name.

Takes an EventName rather than a &str because a name is spliced into a line and a line can be terminated from inside it — the injection is a parse away, and EventName is the parse that closes it. Constructed from a &'static str the way the legacy transport’s two names are; a dynamic name goes through EventName::from_str.

A named frame carries no resume cursor, and that is a property of the transport rather than a restriction: 2024-11-05 has no Last-Event-ID and no replay, so a name is never combined with a cursor on this transport. The two are still representable together for a future transport that does name and resume at once.

Source

pub const fn named_with_id(name: EventName, id: EventId, data: String) -> Self

A named frame that also carries a resume cursor.

Source

pub const fn name(&self) -> Option<&EventName>

The frame’s name, if it has one.

Source

pub fn is_named(&self, event: &EventName) -> bool

Whether this frame is the named event.

Source

pub fn json(id: EventId, value: &Value) -> Result<Self, SseError>

A frame whose data is value serialised as JSON.

The only constructor that takes structured data, and the reason the Debug-formatting bug is unreachable rather than merely discouraged — see the module docs.

§Errors

SseError::Unserialisable if the value cannot be serialised, which for a Value means a non-string map key. The payload is the message the peer receives, so an event that cannot be encoded must not be encoded wrong.

Source

pub const fn id(&self) -> Option<EventId>

The resume cursor, if this frame carries one.

Source

pub fn data(&self) -> &str

The payload, with the frame’s line structure already undone.

Source

pub fn into_data(self) -> String

Consumes the frame, yielding the payload.

The id is dropped rather than returned because the write path uses the payload and the resume cursor comes from the ring that produced the event; a caller that wanted both has the StreamEvent it came from.

Source

pub fn encode(&self) -> String

The bytes to write, without a trailing flush.

event: <name> and id: <n> first when present, then one data: line per line of the payload, then the blank line that dispatches the event. A payload with no newline in it is therefore exactly one data: line, and one with k newlines is k + 1 — which is the claim a_newline_in_the_payload_becomes_another_data_line exists to hold.

Field order is not load-bearing: the standard dispatches on field names, and this decoder does the same. event goes first because that is the order the WHATWG examples use, and a reader that happened to care about order would at least be agreeing with the examples.

Source

pub fn decode(block: &str) -> Result<Self, SseError>

Parses one frame’s block — its lines, without the trailing blank.

§Errors

SseError::NoData if the block carries no data: field, SseError::MalformedId if an id: field is not a decimal event id, and SseError::MalformedName if an event: field is not a usable name.

Source

pub fn dispatch(block: &str) -> Result<Option<Self>, SseError>

The standard’s dispatch, which dispatches nothing for some blocks.

Returns None for a block that is empty or is entirely comments, and that is the load-bearing difference from decode: a keep-alive comment is a legal block that produces no event, and a stream loop that treated it as one would hand its client an empty message every heartbeat.

§Errors

SseError::MalformedId if an id: field is not a decimal event id. A bad cursor is an error rather than a zero: EventId’s 0 is a real, meaningful watermark meaning “before the first event”, and quietly reading a corrupt id as that would tell a client it has seen everything when it has seen nothing.

SseError::MalformedName if an event: field is empty or contains a line terminator. An empty one is refused for the same reason a zero id is not read as a watermark: event: with no value means the default name, and treating it as a name of its own would make Some("") and None two spellings of one dispatch.

Trait Implementations§

Source§

impl Clone for SseEvent

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 SseEvent

Source§

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

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

impl Eq for SseEvent

Source§

impl PartialEq for SseEvent

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 StructuralPartialEq for SseEvent

Auto Trait Implementations§

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more