mod want_one;
mod erased;
pub use erased::ErasedWantFor;
use ty_tag::lifetime_list::LifetimeList;
use ty_tag::{ReifySelf, ReifySized, TagTypeId};
pub use want_one::WantOne;
use crate::Want;
pub trait WantFor<T> {
fn fulfill(&mut self, value: T);
fn is_satisfied(&self) -> bool {
false
}
}
impl<L: LifetimeList> dyn Want<L> + '_ {
pub fn provide_value<T: ReifySelf<L>>(&mut self, value: T) -> &mut Self {
if let Some(want) = self.try_for::<T>() {
want.fulfill(value);
}
self
}
pub fn provide_tag<T: ?Sized + ReifySized<L>>(&mut self, value: T::Reified) -> &mut Self {
if let Some(want) = self.try_for::<T>() {
want.fulfill(value);
}
self
}
pub fn provide<T, F>(&mut self, f: F) -> &mut Self
where
T: ReifySized<L>,
F: FnOnce() -> <T as ReifySized<L>>::SizedReified,
{
if let Some(want) = self.try_for::<T>() {
want.fulfill(f());
}
self
}
pub fn provide_with<T, C, F>(&mut self, ctx: C, f: F) -> Option<C>
where
T: ReifySized<L>,
F: FnOnce(C) -> <T as ReifySized<L>>::SizedReified,
{
if let Some(want) = self.try_for::<T>() {
want.fulfill(f(ctx));
None
} else {
Some(ctx)
}
}
pub fn try_for<T: ?Sized + ReifySized<L>>(&mut self) -> Option<&mut dyn WantFor<T::Reified>> {
let erased = self.try_for_id(TagTypeId::<L>::of_reify::<T>())?;
erased.downcast::<T>().ok()
}
}