fn collect_result<T, E>(mut it: impl ExactSizeIterator<Item = Result<T, E>>) -> Result<Vec<T>, E> {
match it.next() {
None => Ok(Vec::new()),
Some(Err(e)) => Err(e),
Some(Ok(x)) => {
let mut res = Vec::with_capacity(it.len() + 1);
res.push(x);
for x in it {
res.push(x?);
}
Ok(res)
}
}
}
pub trait SliceExt {
type Item;
fn map<'a, B, F>(&'a self, f: F) -> Vec<B>
where
F: FnMut(&'a Self::Item) -> B;
fn try_map<'a, B, E, F>(&'a self, f: F) -> Result<Vec<B>, E>
where
F: FnMut(&'a Self::Item) -> Result<B, E>;
}
impl<T> SliceExt for [T] {
type Item = T;
fn map<'a, B, F>(&'a self, f: F) -> Vec<B>
where
F: FnMut(&'a Self::Item) -> B,
{
self.iter().map(f).collect()
}
fn try_map<'a, B, E, F>(&'a self, f: F) -> Result<Vec<B>, E>
where
F: FnMut(&'a Self::Item) -> Result<B, E>,
{
collect_result(self.iter().map(f))
}
}
pub trait VecExt {
type Item;
fn into_map<B, F>(self, f: F) -> Vec<B>
where
F: FnMut(Self::Item) -> B;
fn into_try_map<B, E, F>(self, f: F) -> Result<Vec<B>, E>
where
F: FnMut(Self::Item) -> Result<B, E>;
}
impl<T> VecExt for Vec<T> {
type Item = T;
fn into_map<B, F>(self, f: F) -> Vec<B>
where
F: FnMut(Self::Item) -> B,
{
self.into_iter().map(f).collect()
}
fn into_try_map<B, E, F>(self, f: F) -> Result<Vec<B>, E>
where
F: FnMut(Self::Item) -> Result<B, E>,
{
collect_result(self.into_iter().map(f))
}
}