#![allow(nonstandard_style)]
use crate::{MapAllMut, Pick, RePick, Tupl};
pub trait IteratorOfTuplesWithF<retval>:
Iterator<Item: Tupl> + Sized
{
/// Map the item at: (|(x, y)| (f(x), y))
fn map_at<const N: usize>(
self,
mut f: impl FnMut(<Self::Item as Pick<N>>::At) -> retval,
) -> core::iter::Map<
Self,
impl FnMut(<Self>::Item) -> <<Self>::Item as RePick<N, retval>>::New,
>
where
Self::Item: RePick<N, retval>,
{
self.map(move |x| {
let (l, at, r) = x.depict();
let at = f(at);
Self::Item::unpick(l, at, r)
})
}
/// filter map the item at: (|(x, y)| f(x).zip(Some(y))
fn filter_map_at<const N: usize>(
self,
mut f: impl FnMut(<Self::Item as Pick<N>>::At) -> Option<retval>,
) -> core::iter::FilterMap<
Self,
impl FnMut(
<Self as Iterator>::Item,
) -> Option<
<<Self as Iterator>::Item as RePick<N, retval>>::New,
>,
>
where
Self::Item: RePick<N, retval>,
{
self.filter_map(move |x| {
let (l, at, r) = x.depict();
f(at).map(|x| Self::Item::unpick(l, x, r))
})
}
/// map the item to just one, then map that one: (|x| f(x.0))
fn map_on<const N: usize>(
self,
f: impl FnMut(<Self::Item as Pick<N>>::At) -> retval,
) -> core::iter::Map<
impl Iterator<Item = <Self::Item as Pick<N>>::At>,
impl FnMut(<Self::Item as Pick<N>>::At) -> retval,
>
where
Self: Iterator<Item: Pick<N>> + Sized,
{
self.on().map(f)
}
fn fmap_on<const N: usize>(
self,
f: impl FnMut(<Self::Item as Pick<N>>::At) -> retval,
) -> core::iter::FlatMap<
core::iter::Map<
Self,
impl FnMut(
<Self as Iterator>::Item,
)
-> <<Self as Iterator>::Item as Pick<N>>::At,
>,
retval,
impl FnMut(<<Self as Iterator>::Item as Pick<N>>::At) -> retval,
>
where
Self::Item: Pick<N>,
retval: IntoIterator,
{
self.on().flat_map(f)
}
}
pub trait IteratorOfReferencesToTupleWithF<'a, T: Tupl + 'a, retval>:
Iterator<Item = &'a T> + Sized
{
/// Map the item at: (|(x, y)| (f(x), y))
fn map_at<const N: usize>(
self,
f: impl FnMut(<T::AsRef<'a> as Pick<N>>::At) -> retval + 'a,
) -> impl Iterator<Item = <T::AsRef<'a> as RePick<N, retval>>::New>
where
T::AsRef<'a>: RePick<N, retval>,
{
self.as_ref().map_at(f)
}
/// map the item to just one, then map that one: (|x| f(x.0))
fn map_on<const N: usize, U>(
self,
f: impl FnMut(<T::AsRef<'a> as Pick<N>>::At) -> U,
) -> core::iter::Map<
impl Iterator<Item = <T::AsRef<'a> as Pick<N>>::At>,
impl FnMut(<T::AsRef<'a> as Pick<N>>::At) -> U,
>
where
T::AsRef<'a>: Pick<N>,
{
self.on().map(f)
}
}
/// may add more later
pub trait IteratorOfTuples: Iterator<Item: Tupl> + Sized {
/// make it just one: (|x| x.0)
fn on<const N: usize>(
self,
) -> core::iter::Map<
Self,
impl FnMut(
<Self as Iterator>::Item,
) -> <<Self as Iterator>::Item as Pick<N>>::At,
>
where
Self::Item: Pick<N>,
{
self.map(|x| x.pick())
}
fn flatten_on<const N: usize>(
self,
) -> core::iter::Flatten<
core::iter::Map<
Self,
impl FnMut(
<Self as Iterator>::Item,
)
-> <<Self as Iterator>::Item as Pick<N>>::At,
>,
>
where
Self::Item: Pick<N, At: IntoIterator>,
{
self.on().flatten()
}
fn map_all<retval: Tupl, functions: Tupl>(
self,
mut fns: functions,
) -> impl Iterator<Item = retval>
where
Self::Item: MapAllMut<retval, functions>,
{
self.map(move |x| x.map_all_mut(&mut fns))
}
}
/// may add more later
pub trait IteratorOfReferencesToTuple<'a, T: Tupl + 'a>:
Iterator<Item = &'a T> + Sized
{
fn as_ref(self) -> core::iter::Map<Self, fn(&T) -> <T>::AsRef<'_>> {
self.map(T::as_ref)
}
/// make it just one: (|x| x.0)
fn on<const N: usize>(
self,
) -> impl Iterator<Item = <T::AsRef<'a> as Pick<N>>::At>
where
T::AsRef<'a>: Pick<N>,
{
self.as_ref().on()
}
fn map_all<retval: Tupl, functions: Tupl>(
self,
mut fns: functions,
) -> impl Iterator<Item = retval>
where
T::AsRef<'a>: MapAllMut<retval, functions>,
{
self.map(move |x| x.as_ref().map_all_mut(&mut fns))
}
}
impl<I: Iterator<Item: Tupl>> IteratorOfTuples for I {}
impl<U, I: Iterator<Item: Tupl>> IteratorOfTuplesWithF<U> for I {}
impl<'a, T: Tupl + 'a, I: Iterator<Item = &'a T>>
IteratorOfReferencesToTuple<'a, T> for I
{
}
impl<'a, U, T: Tupl + 'a, I: Iterator<Item = &'a T>>
IteratorOfReferencesToTupleWithF<'a, T, U> for I
{
}
#[test]
fn x() {
let x = [(1, 2), (3, 4)].iter().map_at::<0>(|x| x + 2);
let y = [(1, "a"), (2, "b")]
.iter()
.map_all((|x| x + 1, |x| x.to_uppercase()))
.next_chunk::<2>()
.unwrap();
}