Skip to main content

Extensions

Struct Extensions 

Source
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 (don’t 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§

Source§

impl Extensions

Source

pub fn new() -> Self

Create an empty Extensions store with no parent.

Source

pub fn fork(&self) -> Self

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.

Source

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

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

Source

pub fn with_base(&self, base: &Self) -> Self

Return a view of this Extensions chain layered on top of base.

The toplevel extensions are still the same and are editable. Lookups resolve through this chain first falling back to base only when nothing matches. base is all the way at the bottom.

Use this when you have an Extensions (chain) to which you want to apply defaults, e.g. request_extensions().with_base(&base_extension_config)

Source

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

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

Source

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

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()

Source

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

Extend this Extensions store with the other Extensions.

The other Extensionss will be appended behind the current ones

Source

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

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.

Source

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

Returns true if this Extensions store contains the given type

This only checks this Extensions store

Source

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

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.

Source

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

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

Source

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

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.

Source

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

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

This only checks this Extensions store

Source

pub fn get_many_ref<'a, T: GetManyRef<'a>>(&'a self) -> T::Output

Fetch several extension types in a single pass, returning a tuple of Option<&T> mirroring the requested tuple. Each slot uses the same search rule as Self::get_ref (newest-wins, walking the Egress / Ingress wrappers and the parent chain), but the whole structure is traversed only once instead of once per type.

See Self::get_many_arc for an owned-Arc variant.

Source

pub fn get_many_arc<T: GetManyArc>(&self) -> T::Output

Like Self::get_many_ref, but returns a tuple of Option<Arc<T>> (cheap, owned Arc clones) instead of borrowed references, the multi-fetch counterpart of Self::get_arc. Same single-pass traversal.

Source

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.

Source

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.

Source

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

Source

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.

Source

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

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 don’t 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”.

Source

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

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

Source

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

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>().

Source

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

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>().

Source

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.

Source

pub fn iter_ref<T: Extension>(&self) -> impl Iterator<Item = &T> + '_

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.

Source

pub fn iter_arc<T: Extension>(&self) -> impl Iterator<Item = Arc<T>> + '_

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

Source

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

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>>()

Source

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

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>>()

Source

pub fn clone_to<T: Extension>(&self, target: &Self) -> Option<Arc<T>>

Clone an Extension from Extensions to another and get a Arc clone of it.

Source

pub fn clone_to_if_absent<T: Extension>(&self, target: &Self) -> Option<Arc<T>>

Clone an Extension from Extensions to another, if and only if the other Extensions store does not already contain this Extension T.

If the other Extensions store already contains it, we return Extension T from the other store, otherwise we return the T that we transferred over.

This is mainly used in connectors where Extensions that become part of the connection should be transfer from the input to the connection.

Trait Implementations§

Source§

impl Clone for Extensions

Source§

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

impl Debug for Extensions

Source§

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

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

impl Default for Extensions

Source§

fn default() -> Extensions

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

impl ExtensionsRef for Extensions

Source§

fn extensions(&self) -> &Extensions

Get reference to the underlying Extensions store

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

Source§

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

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

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
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> 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
Source§

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

Source§

fn rama_from(value: T) -> U

Source§

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

Source§

fn rama_into(self) -> U

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

Source§

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

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

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

Source§

fn vzip(self) -> V

Source§

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

Source§

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

Write value to writer
Source§

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

Source§

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

Write value to writer
Source§

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

Source§

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

Write value to writer
Source§

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

Source§

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

Write value to writer
Source§

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

Source§

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

Write value to writer
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