use std::borrow::Borrow;
use crate::dupe::Dupe;
use crate::types::TEq;
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>;
fn owned<'a, T, R>(&'a self) -> Vec<R>
where
Self::Item: TEq<&'a T>,
R: Borrow<T>,
T: ToOwned<Owned = R>,
T: 'a,
T: ?Sized,
{
self.map(|x| (*x.teq_ref()).to_owned())
}
fn as_singleton(&self) -> Option<&Self::Item>;
fn dupe_from_slice(&mut self, src: &[Self::Item])
where
Self::Item: Dupe;
}
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))
}
fn as_singleton(&self) -> Option<&T> {
match self {
[x] => Some(x),
_ => None,
}
}
fn dupe_from_slice(&mut self, src: &[Self::Item])
where
Self::Item: Dupe,
{
self.clone_from_slice(src)
}
}
pub trait SliceClonedExt {
type Item;
fn cloned(&self) -> Vec<Self::Item>;
}
impl<T> SliceClonedExt for [&T]
where
T: Clone,
{
type Item = T;
fn cloned(&self) -> Vec<Self::Item> {
self.map(|x| (*x).clone())
}
}
pub trait SliceDupedExt {
type Item;
fn duped(&self) -> Vec<Self::Item>;
}
impl<T> SliceDupedExt for [&T]
where
T: Dupe,
{
type Item = T;
fn duped(&self) -> Vec<Self::Item> {
self.map(|x| (*x).dupe())
}
}
pub trait SliceCopiedExt {
type Item;
fn copied(&self) -> Vec<Self::Item>;
}
impl<T> SliceCopiedExt for [&T]
where
T: Copy,
{
type Item = T;
fn copied(&self) -> Vec<Self::Item> {
self.map(|x| **x)
}
}
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))
}
}