supply 0.3.1

Provider API for arbitrary number of lifetimes.
Documentation
use ty_tag::lifetime_list::LifetimeList;
use ty_tag::{ReifySized, TagTypeId};

use super::{ErasedWantFor, Want, WantFor};

/// Want for a single value.
pub struct WantOne<L: LifetimeList, T: ?Sized + ReifySized<L>>(Option<T::Reified>);

impl<T: ?Sized + ReifySized<L>, L: LifetimeList> Default for WantOne<L, T> {
    fn default() -> Self {
        Self(None)
    }
}

impl<T: ?Sized + ReifySized<L>, L: LifetimeList> WantOne<L, T> {
    /// Create want with a possibly set value.
    ///
    /// If `value` is `Some` then this want will always be satisfied.
    /// However, if a new value is provided it will replace the one given.
    pub const fn new(value: Option<T::Reified>) -> Self {
        Self(value)
    }

    /// Convert into the inner option value.
    pub fn into_inner(self) -> Option<T::Reified> {
        self.0
    }
}

impl<T, L> Want<L> for WantOne<L, T>
where
    T: ?Sized + ReifySized<L>,
    L: LifetimeList,
{
    fn try_for_id(&mut self, tag_type_id: TagTypeId<L>) -> Option<ErasedWantFor<'_, L>> {
        // To play nicely with the request combinators we need to only return
        // if we can be provided the type.
        if tag_type_id == TagTypeId::<L>::of_reify::<T>() {
            // The caller will be able to use fulfill from the WantFor below.
            Some(ErasedWantFor::new::<T>(self))
        } else {
            None
        }
    }

    fn is_satisfied(&self) -> bool {
        // If the option has a value then the want is satisfied.
        self.0.is_some()
    }
}

impl<T: ?Sized + ReifySized<L>, L: LifetimeList> WantFor<T::Reified> for WantOne<L, T> {
    fn fulfill(&mut self, value: <T>::Reified) {
        // Stick the value in the option.
        self.0 = Some(value);
    }

    fn is_satisfied(&self) -> bool {
        // If the option has a value then the want is satisfied.
        self.0.is_some()
    }
}