pub struct OutgoingMessage<'a, Payload = &'a [u8]> { /* private fields */ }Expand description
A message ready to be published: a borrowed destination, a payload in the form its publisher declared, and the header map the publish filled.
The payload type is the publisher’s own declaration (Publisher::Payload): &'a [u8] for a
transport that reads the bytes, BytesMut for one whose client keeps them. It defaults to
the lending form, so OutgoingMessage<'a> is the message a reading transport receives.
payload reads either, into_payload takes the form
itself, and into_parts takes the destination, the payload and the map in
one move, nothing copied - what a transport that consumes the message calls.
new builds one over bytes the caller holds, whichever form the publisher asked
for: free where it lends, one copy where it keeps them. A publish that produced the buffer
itself - the codec’s output - hands it over with produced.
§Examples
use ruststream::{HeaderMap, OutgoingMessage};
let payload = b"{\"hello\":\"world\"}";
let mut headers = HeaderMap::new();
headers.insert("Content-Type", "application/json");
// A publish names the form through the publisher it goes to; on its own, the message names
// it here, and the lending form is the default.
let msg: OutgoingMessage<'_> =
OutgoingMessage::new("orders.created", payload).with_headers(headers);
assert_eq!(msg.name(), "orders.created");
assert_eq!(msg.payload(), payload);
// What a transport that keeps the message takes, in the one call that ends it.
let (name, body, headers) = msg.into_parts();
assert_eq!(name, "orders.created");
assert_eq!(body, payload);
assert_eq!(
headers.content_type().ok_or("the publish named no content type")?,
"application/json",
);Implementations§
Source§impl<'a, Payload> OutgoingMessage<'a, Payload>
impl<'a, Payload> OutgoingMessage<'a, Payload>
Sourcepub fn with_payload(name: &'a str, payload: Payload) -> Self
pub fn with_payload(name: &'a str, payload: Payload) -> Self
Constructs a new outgoing message over a payload already in the publisher’s form, with no headers.
What a stage that rebuilds a message uses, so a buffer already handed over is not downgraded to a borrow on the way.
§Examples
use ruststream::OutgoingMessage;
let carried: &[u8] = OutgoingMessage::new("orders.created", b"{}").into_payload();
let msg = OutgoingMessage::with_payload("orders.rebuilt", carried);
assert_eq!(msg.payload(), b"{}");Sourcepub fn with_headers(self, headers: HeaderMap) -> Self
pub fn with_headers(self, headers: HeaderMap) -> Self
Builder-style setter that replaces the header map.
Sourcepub fn with_typed_headers<T: Serialize + ?Sized>(
self,
value: &T,
) -> Result<Self, SerializeHeadersError>
pub fn with_typed_headers<T: Serialize + ?Sized>( self, value: &T, ) -> Result<Self, SerializeHeadersError>
Builder-style setter that serializes a typed contract into the headers, one entry per
field (see HeaderMap::insert_typed). Entries already present under other names are kept.
§Errors
Returns SerializeHeadersError when the value is not a flat struct or string-keyed map.
§Examples
use ruststream::OutgoingMessage;
use serde::Serialize;
#[derive(Serialize)]
struct ChunkMeta {
task_id: u64,
}
let msg: OutgoingMessage<'_> = OutgoingMessage::new("chunks.done", b"{}")
.with_typed_headers(&ChunkMeta { task_id: 7 })?;
assert_eq!(msg.headers().get_str("task_id"), Some("7"));Sourcepub fn name(&self) -> &'a str
pub fn name(&self) -> &'a str
Returns the name / subject this message will be published to.
The name is the caller’s, not the message’s, so it outlives the message: a transport reads the destination here and then consumes the message for its payload.
Sourcepub fn into_payload(self) -> Payload
pub fn into_payload(self) -> Payload
Returns the payload in the form this publisher declared.
What a transport calls to send: a lending one gets the slice it reads, a taking one the buffer it keeps. Publishing takes the message by value, so there is no by-reference counterpart - a borrow cannot hand a buffer over, so it would have to copy.
§Examples
use ruststream::{BytesMut, OutgoingMessage};
let msg = OutgoingMessage::produced("orders.created", BytesMut::from(&b"{}"[..]));
let buffer: BytesMut = msg.into_payload();
assert_eq!(Vec::from(buffer), b"{}".to_vec());Sourcepub fn headers(&self) -> &HeaderMap
pub fn headers(&self) -> &HeaderMap
Returns a shared reference to the headers.
What a transport that only walks the map reads. One that hands the map on to its client
takes it with into_parts rather than cloning it.
Sourcepub fn into_parts(self) -> (&'a str, Payload, HeaderMap)
pub fn into_parts(self) -> (&'a str, Payload, HeaderMap)
The destination, the payload and the header map, taken in one move.
What a transport that consumes the message calls: publishing owns the message, so the
name it was addressed to, the payload in its declared form and the map the transforms
filled all arrive at once, with nothing copied. The name is the caller’s, so it outlives
the message it came out of. There is no second consuming accessor to pair this with:
into_payload already ends the message, so a transport that wants
the map as well asks for everything here.
§Examples
use ruststream::{BytesMut, HeaderMap, OutgoingMessage};
let mut headers = HeaderMap::new();
headers.insert("Content-Type", "application/json");
let msg = OutgoingMessage::produced("orders.created", BytesMut::from(&b"{}"[..]))
.with_headers(headers);
let (name, payload, headers) = msg.into_parts();
assert_eq!(name, "orders.created");
assert_eq!(Vec::from(payload), b"{}".to_vec());
assert_eq!(
headers.content_type().ok_or("the publish named no content type")?,
"application/json",
);Source§impl<'a, Payload: From<&'a [u8]>> OutgoingMessage<'a, Payload>
impl<'a, Payload: From<&'a [u8]>> OutgoingMessage<'a, Payload>
Sourcepub fn new(name: &'a str, payload: &'a [u8]) -> Self
pub fn new(name: &'a str, payload: &'a [u8]) -> Self
Constructs a new outgoing message over bytes the caller holds, with no headers.
The bytes arrive in the publisher’s own form: lent as they are to a transport that reads
them, copied into a buffer of its own for one that keeps them. A publish that produced
the buffer itself hands it over with produced instead, which copies
nowhere.
Source§impl<'a> OutgoingMessage<'a, BytesMut>
impl<'a> OutgoingMessage<'a, BytesMut>
Sourcepub fn produced(name: &'a str, payload: BytesMut) -> Self
pub fn produced(name: &'a str, payload: BytesMut) -> Self
Constructs a new outgoing message handing over a buffer just written, with no headers.
What a publish that produced the payload for a taking transport uses: the buffer travels as it was written, and whoever takes it decides what to make of it.
§Examples
use ruststream::{BytesMut, OutgoingMessage};
let msg = OutgoingMessage::produced("orders.created", BytesMut::from(&b"{}"[..]));
assert_eq!(msg.payload(), b"{}");Trait Implementations§
Source§impl<'a, Payload: Clone> Clone for OutgoingMessage<'a, Payload>
impl<'a, Payload: Clone> Clone for OutgoingMessage<'a, Payload>
Auto Trait Implementations§
impl<'a, Payload> Freeze for OutgoingMessage<'a, Payload>where
Payload: Freeze,
impl<'a, Payload> RefUnwindSafe for OutgoingMessage<'a, Payload>where
Payload: RefUnwindSafe,
impl<'a, Payload> Send for OutgoingMessage<'a, Payload>where
Payload: Send,
impl<'a, Payload> Sync for OutgoingMessage<'a, Payload>where
Payload: Sync,
impl<'a, Payload> Unpin for OutgoingMessage<'a, Payload>where
Payload: Unpin,
impl<'a, Payload> UnsafeUnpin for OutgoingMessage<'a, Payload>where
Payload: UnsafeUnpin,
impl<'a, Payload> UnwindSafe for OutgoingMessage<'a, Payload>where
Payload: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request