use crate::{
    nest::NestValueType,
    transform::Transform,
};

/// Fallible version of [`BuildNestValue`](crate::BuildNestValue)
///
/// See [`BuildNestValue`](crate::BuildNestValue) for more information
pub trait TryBuildNestValue<T, V>: Transform
where
    V: NestValueType
{
    type Error;

    fn try_build_nest_value(&self, source: &T, options: &Self::Options) -> Result<V, Self::Error>;
}


/// Auto-implement for option -> option
impl<I, O, T> TryBuildNestValue<Option<I>, Option<O>> for T where
    O: NestValueType,
    T: Transform,
    Self: TryBuildNestValue<I, O>,
{
    type Error = <Self as TryBuildNestValue<I, O>>::Error;

    fn try_build_nest_value(&self, source: &Option<I>, options: &Self::Options) -> Result<Option<O>, Self::Error> {
        source.as_ref().map(|s| {
            self.try_build_nest_value(s, options)
        }).transpose()
    }
}
