Module error_stack::provider
source · [−]nightly
only.Expand description
Contains the Provider
trait and accompanying API, which enable trait objects to provide data
based on typed requests, an alternate form of runtime reflection.
Provider
and Demand
Provider
and the associated APIs support generic, type-driven access to data, and a mechanism
for implementers to provide such data. The key parts of the interface are the Provider
trait for objects which can provide data, and the request_value
and request_ref
functions for requesting data from an object which implements Provider
. Generally, end users
should not call request_*
directly, they are helper functions for intermediate implementers
to use to implement a user-facing interface.
Typically, a data provider is a trait object of a trait which extends Provider
. A user will
request data from a trait object by specifying the type of the data.
Data flow
- A user requests an object of a specific type, which is delegated to
request_value
orrequest_ref
request_*
creates aDemand
object and passes it toProvider::provide
- The data provider’s implementation of
Provider::provide
tries providing values of different types usingDemand::provide_*
. If the type matches the type requested by the user, the value will be stored in theDemand
object. request_*
unpacks theDemand
object and returns any stored value to the user.
Examples
use error_stack::provider::{request_ref, Demand, Provider};
// Definition of MyTrait, a data provider.
trait MyTrait: Provider {
// ...
}
// Methods on `MyTrait` trait objects.
impl dyn MyTrait + '_ {
/// Get a reference to a field of the implementing struct.
pub fn get_context_by_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
request_ref::<T, _>(self)
}
}
// Downstream implementation of `MyTrait` and `Provider`.
impl MyTrait for SomeConcreteType {
// ...
}
impl Provider for SomeConcreteType {
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
// Provide a string reference. We could provide multiple values with
// different types here.
demand.provide_ref::<String>(&self.some_string);
}
}
// Downstream usage of `MyTrait`.
fn use_my_trait(obj: &dyn MyTrait) {
// Request a &String from obj.
let _ = obj.get_context_by_ref::<String>().unwrap();
}
In this example, if the concrete type of obj
in use_my_trait
is SomeConcreteType
, then
the get_context_ref
call will return a reference to obj.some_string
with type &String
.
Structs
A helper object for providing data by type.
Traits
Trait implemented by a type which can dynamically provide values based on type.
Functions
Request a reference from the Provider
.
Request a value from the Provider
.