Skip to main content

Extensions

Struct Extensions 

pub struct Extensions { /* private fields */ }
Expand description

A type map of protocol extensions.

Extensions are internally stored in a type erased Arc. Since values are stored in an Arc there are extra methods exposed that build on top of this and leverage characteristics of an Arc to expose things like cheap cloning of the Arc.

Extensions may have an optional parent: the Extensions this one was forked from. Lookups walk the parent chain when the local Extensions don’t have the requested type. The parent relationship is best described as “I’m layered on top of that, but I’m not exactly the same”:

  • Retry attempts fork from the original request (dont leak failed extensions)
  • Responses fork the request (response != request)
  • H2 streams fork from underlying H2 connection (nested connection with isolated properties)

Connection’s who logically map one-to-one we don’t fork and we just pass the Extensions up, examples are:

  • TLS layered on top of TCP
  • HTTP layered on top of TLS

Implementations§

§

impl Extensions

pub fn new() -> Extensions

Create an empty Extensions store with no parent.

pub fn fork(&self) -> Extensions

Create a fresh child Extensions whose parent is this Extensions store.

The child has its own empty top-level storage. Lookups that miss locally walk into the parent (and recursively up the chain). Inserts land on this child only, parents are never mutated through the child.

pub fn parent(&self) -> Option<&Extensions>

The parent Extensions this blob was forked from, if any.

pub fn insert<T>(&self, val: T) -> &T
where T: Extension,

Insert a type T into this Extensions store.

This method returns a reference to the just inserted value.

If the value you are inserting is an Arc<T>, prefer using Self::insert_arc to prevent the double indirection of storing an Arc<Arc<T>>.

pub fn insert_arc<T>(&self, val: Arc<T>) -> Arc<T>
where T: Extension,

Insert a type Arc<T> into this [Extensions] store.

This method returns a a cloned Arc of the value just inserted

If the value you are inserting is not an Arc<T> or you don’t need a cloned Arc<T> prefer using Self::insert()

pub fn extend(&self, other: &Extensions)

Extend this Extensions store with the other Extensions.

The other Extensionss will be appended behind the current ones

pub fn contains<T>(&self) -> bool
where T: Extension,

Returns true if the Extensions store contains the given type.

This function is recursive and will traverse multiple nested Extensions stores to find the correct item. See Extensions::get_ref() for how this works.

If you don’t want any of this special logic and you just want to check this Extensions store, use Extensions::self_contains() instead.

pub fn self_contains<T>(&self) -> bool
where T: Extension,

Returns true if this Extensions store contains the given type

This only checks this Extensions store

pub fn get_ref<T>(&self) -> Option<&T>
where T: Extension,

Get a reference to T. Walks the parent chain and the connection wrappers (Egress / Ingress) if not found locally.

Search rule (single pass, newest insertion wins):

  1. Iterate local entries newest -> oldest. For each entry:
    • if its type matches T, return it,
    • if it is an Egress<Extensions> or Ingress<Extensions> wrapper, recurse into the wrapped blob with the same rule (its own local first, then its wrappers, then its parent) and return any match found,
    • otherwise skip.
  2. If still not found, recurse into the parent (same rule applied).

Wrappers are spliced into the local scan in insertion order, so a connection-pointer detour inserted on this blob is treated as part of “local” for ordering purposes: a directly-inserted T and a wrapper containing T both compete by insertion time, newest wins. Parent is only consulted after the entire local scan (including wrapper recursion) finishes empty. The wrappers themselves can still be retrieved directly (or via Self::egress / Self::ingress).

For a raw flat lookup, use Self::self_get_ref.

Returns the most recently inserted match, for the oldest, see Self::self_first_ref.

pub fn self_get_ref<T>(&self) -> Option<&T>
where T: Extension,

Raw flat Self::get_ref: returns the most recently inserted T, for the oldest, see Self::self_first_ref.

This only checks this Extensions store

pub fn get_arc<T>(&self) -> Option<Arc<T>>
where T: Extension,

Get an owned Arc<T>. Walks the parent chain and the structural connection wrappers if not found locally.

See Self::get_ref for the search order.

For a raw flat lookup (top-level only), use Self::self_get_arc.

pub fn self_get_arc<T>(&self) -> Option<Arc<T>>
where T: Extension,

Raw flat Self::get_arc: returns the most recently inserted T

This only checks this Extensions store

pub fn get_ref_or_insert<T, F>(&self, create_fn: F) -> &T
where T: Extension, F: FnOnce() -> T,

Recursive find-or-create: return &T if one exists anywhere in this this Extensions store (using Self::get_ref dispatch), otherwise insert the value produced by create_fn at the top level and return a reference to it.

Useful when a type conceptually belongs to the scope (e.g. ConnectionHealth on a connection chain) and you want to reuse an existing instance rather than create a duplicate at every layer. For strict “ensure local exists”, use Self::self_get_ref_or_insert.

pub fn get_arc_or_insert<T, F>(&self, create_fn: F) -> Arc<T>
where T: Extension, F: FnOnce() -> Arc<T>,

Recursive find-or-create returning an Arc<T>: see Self::get_ref_or_insert.

pub fn self_get_ref_or_insert<T, F>(&self, create_fn: F) -> &T
where T: Extension, F: FnOnce() -> T,

Raw flat find-or-create: return &T if one exists at the top level of this Extensions store, otherwise insert the value produced by create_fn at the top level and return a reference to it.

Does not follow the parent chain. Useful when you want strict “ensure T exists on THIS blob” (e.g. materializing a direction wrapper like Ingress<Connection<Extensions>> at the outer blob).

pub fn self_get_arc_or_insert<T, F>(&self, create_fn: F) -> Arc<T>
where T: Extension, F: FnOnce() -> Arc<T>,

Raw flat find-or-create returning an Arc<T>: see Self::self_get_ref_or_insert.

pub fn self_first_ref<T>(&self) -> Option<&T>
where T: Extension,

Raw flat reference to the oldest inserted T at the top level of this Extensions store, does not walk structural wrappers.

In most cases you want Self::get_ref (newest, scope-aware). Use this only when you specifically need insertion order access inside this Extensions store.

Currently we dont provide a recursive variant of this method since we don’t have a use case for it, and it’s not exactly clear what would be considered “first”.

pub fn self_first_arc<T>(&self) -> Option<Arc<T>>
where T: Extension,

Raw flat Arc<T> to the oldest inserted T at the top level, see Self::self_first_ref for caveats.

pub fn self_iter_ref<T>(&self) -> impl Iterator<Item = &T>
where T: Extension,

Raw flat iteration over all inserted items of type T at the top level of this Extensions store, newest to oldest.

The order matches Self::self_get_ref (newest-first), so self_iter_ref::<T>().next() == self_get_ref::<T>().

pub fn self_iter_arc<T>(&self) -> impl Iterator<Item = Arc<T>>
where T: Extension,

Raw flat iteration over all inserted items of type T at the top level as cloned Arc values, newest to oldest.

The order matches Self::self_get_arc (newest-first), so self_iter_arc::<T>().next() == self_get_arc::<T>().

pub fn self_iter_all(&self) -> impl Iterator<Item = &TypeErasedExtension>

Raw flat iteration over all TypeErasedExtension entries at the top level of this Extensions store.

Use to efficiently combine different types of Extensions in a single iteration. TypeErasedExtension exposes methods to convert back to type T when it matches the erased type.

pub fn iter_ref<T>(&self) -> impl Iterator<Item = &T>
where T: Extension,

Iterate over all inserted items of type T, walking the parent chain and the structural Egress / Ingress connection wrappers.

Yield order matches Self::get_ref preference (so iter_ref::<T>().next() == get_ref::<T>()):

At each level, iterate the local entries newest -> oldest. For each entry: yield it if its type matches T, if it is an Egress<Extensions> or Ingress<Extensions> wrapper, recurse into the wrapped blob (same rule applied) and yield its results inline. Then recurse into the parent.

For a flat top-level-only iteration use Self::self_iter_ref.

The iterator type is left opaque (impl Iterator) so the internal representation can change without breaking callers.

pub fn iter_arc<T>(&self) -> impl Iterator<Item = Arc<T>>
where T: Extension,

Iteration yielding cloned Arc<T> values, see Self::iter_ref.

pub fn ingress(&self) -> Option<&Ingress<Extensions>>

Get a reference to the Ingress<Extensions> wrapper if one exists on this blob or anywhere reachable through the parent chain.

Returns None when no ingress wrapper has been set up. For correctly constructed server-side requests this is always Some, server stacks insert the wrapper at the boundary where the connection becomes visible to a request, so a None here is almost always a framework setup bug rather than a normal state.

This is just a shortcut for extensions.get_ref::<Ingress<Extensions>>()

pub fn egress(&self) -> Option<&Egress<Extensions>>

Get a reference to the Egress<Extensions> wrapper if one exists on this blob or anywhere reachable through the parent chain. See Self::ingress for semantics.

This is just a shortcut for extensions.get_ref::<Egress<Extensions>>()

Trait Implementations§

§

impl Clone for Extensions

§

fn clone(&self) -> Extensions

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
§

impl Debug for Extensions

§

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

Formats the value using the given formatter. Read more
§

impl Default for Extensions

§

fn default() -> Extensions

Returns the “default value” for a type. Read more
§

impl ExtensionsRef for Extensions

§

fn extensions(&self) -> &Extensions

Get reference to the underlying Extensions store
§

impl FromRequest for Extensions

§

type Rejection = Infallible

If the extractor fails it’ll use this “rejection” type. A rejection is a kind of error that can be converted into a response.
§

async fn from_request( req: Request, ) -> Result<Extensions, <Extensions as FromRequest>::Rejection>

Perform the extraction.
§

impl IntoResponse for Extensions

§

fn into_response(self) -> Response

Create a response.
§

impl IntoResponseParts for Extensions

§

type Error = Infallible

The type returned in the event of an error. Read more
§

fn into_response_parts( self, res: ResponseParts, ) -> Result<ResponseParts, <Extensions as IntoResponseParts>::Error>

Set parts of the response

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
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

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

§

fn from_ref(input: &T) -> T

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

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

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

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

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<R> IntoEndpointService<()> for R
where R: IntoResponse + Clone + Send + Sync + 'static,

§

impl<R, State> IntoEndpointServiceWithState<(), State> for R
where R: IntoResponse + Clone + Send + Sync + 'static,

§

type Service = StaticService<R>

§

fn into_endpoint_service_with_state( self, _state: State, ) -> <R as IntoEndpointServiceWithState<(), State>>::Service

convert the type into a rama_core::Service with state.
§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a rama_grpc::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: 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
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: 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
§

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

§

fn rama_from(value: T) -> U

§

impl<T, U, CrateMarker> RamaInto<U, CrateMarker> for T
where U: RamaFrom<T, CrateMarker>,

§

fn rama_into(self) -> U

§

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

§

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

§

fn rama_try_from(value: T) -> Result<U, <U as RamaTryFrom<T>>::Error>

§

impl<T, U, CrateMarker> RamaTryInto<U, CrateMarker> for T
where U: RamaTryFrom<T, CrateMarker>,

§

type Error = <U as RamaTryFrom<T, CrateMarker>>::Error

§

fn rama_try_into(self) -> Result<U, <U as RamaTryFrom<T, CrateMarker>>::Error>

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.
§

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

§

fn vzip(self) -> V

§

impl<V, F> ValueFormatter<&V> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

fn format_value(writer: impl ValueWriter, value: &&V)

Write value to writer
§

impl<V, F> ValueFormatter<Arc<V>> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

fn format_value(writer: impl ValueWriter, value: &Arc<V>)

Write value to writer
§

impl<V, F> ValueFormatter<Box<V>> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

fn format_value(writer: impl ValueWriter, value: &Box<V>)

Write value to writer
§

impl<V, F> ValueFormatter<Cow<'_, V>> for F
where V: ToOwned + ?Sized, F: ValueFormatter<V> + ?Sized,

§

fn format_value(writer: impl ValueWriter, value: &Cow<'_, V>)

Write value to writer
§

impl<V, F> ValueFormatter<Option<V>> for F
where F: ValueFormatter<V> + ?Sized,

§

fn format_value(writer: impl ValueWriter, value: &Option<V>)

Write value to writer
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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