use smallvec::SmallVec; use std::collections::BTreeMap; use std::convert::Infallible; use std::fmt::Debug; /// Partial variant of `std::iter::FromIterator`. /// /// This trait is implemented for types which can be constructed from an iterator of decoded SSZ /// values, but which may refuse values once a length limit is reached. pub trait TryFromIter: Sized { type Error: Debug; fn try_from_iter(iter: I) -> Result where I: IntoIterator; } // It would be nice to be able to do a blanket impl, e.g. // // `impl TryFromIter for C where C: FromIterator` // // However this runs into trait coherence issues due to the type parameter `T` on `TryFromIter`. // // E.g. If we added an impl downstream for `List` then another crate downstream of that // could legally add an impl of `FromIterator for List` which would create // two conflicting implementations for `List`. Hence the `List` impl is disallowed // by the compiler in the presence of the blanket impl. That's obviously annoying, so we opt to // abandon the blanket impl in favour of impls for selected types. impl TryFromIter for Vec { type Error = Infallible; fn try_from_iter(iter: I) -> Result where I: IntoIterator, { Ok(Self::from_iter(iter)) } } impl TryFromIter for SmallVec<[T; N]> { type Error = Infallible; fn try_from_iter(iter: I) -> Result where I: IntoIterator, { Ok(Self::from_iter(iter)) } } impl TryFromIter<(K, V)> for BTreeMap where K: Ord, { type Error = Infallible; fn try_from_iter(iter: I) -> Result where I: IntoIterator, { Ok(Self::from_iter(iter)) } } /// Partial variant of `collect`. pub trait TryCollect: Iterator { fn try_collect(self) -> Result where C: TryFromIter; } impl TryCollect for I where I: Iterator, { fn try_collect(self) -> Result where C: TryFromIter, { C::try_from_iter(self) } }