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_valueorrequest_ref request_*creates aDemandobject and passes it toProvider::provide- The data provider’s implementation of
Provider::providetries providing values of different types usingDemand::provide_*. If the type matches the type requested by the user, the value will be stored in theDemandobject. request_*unpacks theDemandobject 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.