supply 0.1.0

Provider API for arbitrary number of lifetimes.
Documentation
use super::{ErasedWantFor, WantFor};
use crate::tag::{ReifySized, TagTypeId};
use crate::{Lt1, LtList, Want};

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

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

impl<'r, T: ?Sized + ReifySized<Lt1<'r, L>>, L: LtList> WantOne<'r, 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 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<'r, T, L> Want<'r, L> for WantOne<'r, L, T>
where
    T: ?Sized + ReifySized<Lt1<'r, L>>,
    L: LtList,
{
    fn try_for_id(
        &mut self,
        tag_type_id: TagTypeId<Lt1<'r, L>>,
    ) -> Option<ErasedWantFor<'_, Lt1<'r, L>>> {
        // To play nicely with the request combinators we need to only return
        // if we can be provided the type.
        if tag_type_id.is_same(&TagTypeId::<Lt1<'r, L>>::of::<T::Tag, T::Lifetimes>()) {
            // The caller will be able to use provide 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<'r, T: ?Sized + ReifySized<Lt1<'r, L>>, L: LtList> WantFor<T::Lifetimes, T::Tag>
    for WantOne<'r, L, T>
{
    fn fulfill(&mut self, value: <T>::Reified) {
        // Stick the value in the option.
        self.0 = Some(value);
    }

    fn is_satisfied(&self) -> bool {
        self.0.is_some()
    }
}