pub(crate) mod sealed {
pub trait Collectable<T> {
type Collection;
fn initialize() -> Self::Collection;
fn extend(collection: &mut Self::Collection, item: T) -> bool;
fn finalize(collection: Self::Collection) -> Self;
}
}
impl<T> sealed::Collectable<T> for Vec<T> {
type Collection = Self;
fn initialize() -> Self::Collection {
Vec::default()
}
fn extend(collection: &mut Self::Collection, item: T) -> bool {
collection.push(item);
true
}
fn finalize(collection: Self::Collection) -> Self {
collection
}
}
impl<T, U, E> sealed::Collectable<Result<T, E>> for Result<U, E>
where
U: sealed::Collectable<T>,
{
type Collection = Result<U::Collection, E>;
fn initialize() -> Self::Collection {
Ok(U::initialize())
}
fn extend(collection: &mut Self::Collection, item: Result<T, E>) -> bool {
match item {
Ok(item) => {
let collection = collection.as_mut().ok().expect("invalid state");
U::extend(collection, item)
}
Err(e) => {
*collection = Err(e);
false
}
}
}
fn finalize(collection: Self::Collection) -> Self {
match collection {
Ok(collection) => Ok(U::finalize(collection)),
err @ Err(_) => Err(err.map(drop).unwrap_err()),
}
}
}