pub struct Ctx<K>(pub <K as CtxKey>::Value)
where
K: CtxKey;Expand description
Extractor that injects one broker context field into a handler, by its key.
Where State<T> pulls a value out of the shared application state, Ctx<K> pulls
one field out of the broker’s per-delivery context: Ctx(offset): Ctx<Offset> binds the
value the key Offset reads. The key implements ContextField, which names the context
type it reads from - so a handler using only Ctx extractors needs no &mut Context
parameter at all: the #[subscriber] macro projects the subscription’s context type from
the first Ctx key in the signature. With a &mut Context<'_, C> parameter also present,
the keys must read that same C (the compiler enforces it).
Values are owned (ContextField::Value is 'static): extractors bind before the handler
body runs, so borrowing from the context is not an option. Keys yielding borrowed values
stay readable through ctx.context(KEY).
§Examples
use ruststream::ContextField;
use ruststream::prelude::*;
use serde::Deserialize;
/// A broker's per-delivery context, and its key for the offset a delivery sits at.
struct Delivery {
offset: u64,
}
#[derive(Clone, Copy, Default)]
struct Offset;
impl ContextField for Offset {
type Context = Delivery;
type Value = u64;
fn read(self, src: &Delivery) -> u64 {
src.offset
}
}
#[derive(Deserialize)]
struct Order {
id: u64,
}
#[subscriber("orders")]
async fn audit(order: &Order, Ctx(offset): Ctx<Offset>) -> HandlerOutcome {
tracing::info!(order.id, offset, "audited");
HandlerOutcome::ack()
}Tuple Fields§
§0: <K as CtxKey>::ValueTrait Implementations§
Source§impl<S, K> FromContext<<K as ContextField>::Context, S> for Ctx<K>
impl<S, K> FromContext<<K as ContextField>::Context, S> for Ctx<K>
Source§type Rejection = !
type Rejection = !
HandlerOutcome (the
reflexive conversion makes HandlerOutcome itself a valid rejection, and Infallible
works for an extractor that never fails) and the delivery is settled by that outcome,
skipping the handler body.Source§fn from_context(
ctx: &mut Context<'_, <K as ContextField>::Context, S>,
) -> impl Future<Output = Result<Ctx<K>, !>> + Send
fn from_context( ctx: &mut Context<'_, <K as ContextField>::Context, S>, ) -> impl Future<Output = Result<Ctx<K>, !>> + Send
Source§impl<C, S> FromContext<C, S> for Ctx<MainRuntime>
impl<C, S> FromContext<C, S> for Ctx<MainRuntime>
Source§type Rejection = !
type Rejection = !
HandlerOutcome (the
reflexive conversion makes HandlerOutcome itself a valid rejection, and Infallible
works for an extractor that never fails) and the delivery is settled by that outcome,
skipping the handler body.Auto Trait Implementations§
impl<K> Freeze for Ctx<K>
impl<K> RefUnwindSafe for Ctx<K>
impl<K> Send for Ctx<K>
impl<K> Sync for Ctx<K>
impl<K> Unpin for Ctx<K>
impl<K> UnsafeUnpin for Ctx<K>
impl<K> UnwindSafe for Ctx<K>
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> 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 more