use crate::{Pick, RePick, Tupl};
/// may add more later
pub trait IteratorOfTuples: Iterator<Item: Tupl> {
/// Map the item at: (|(x, y)| (f(x), y))
fn map_at<const N: usize, U>(
self,
f: impl FnMut(<Self::Item as Pick<N>>::At) -> U,
) -> impl Iterator<Item = <Self::Item as RePick<N, U>>::New>
where
Self::Item: RePick<N, U>;
/// make it just one: (|x| x.0)
fn just<const N: usize>(
self,
) -> impl Iterator<Item = <Self::Item as Pick<N>>::At>
where
Self::Item: Pick<N>;
/// map the item to just one, then map that one: (|x| f(x.0))
fn map_just<const N: usize, U>(
self,
f: impl FnMut(<Self::Item as Pick<N>>::At) -> U,
) -> core::iter::Map<
impl Iterator<Item = <Self::Item as Pick<N>>::At>,
impl FnMut(<Self::Item as Pick<N>>::At) -> U,
>
where
Self: Iterator<Item: Pick<N>> + Sized,
{
self.just().map(f)
}
}
impl<I: Iterator<Item: Tupl>> IteratorOfTuples for I {
#[expect(refining_impl_trait)]
fn map_at<const N: usize, U>(
self,
mut f: impl FnMut(<Self::Item as Pick<N>>::At) -> U,
) -> core::iter::Map<
I,
impl FnMut(
<I as Iterator>::Item,
) -> <<I as Iterator>::Item as RePick<N, U>>::New,
>
where
Self::Item: RePick<N, U>,
{
self.map(move |x| {
let (l, at, r) = x.depict();
let at = f(at);
Self::Item::unpick(l, at, r)
})
}
#[expect(refining_impl_trait)]
fn just<const N: usize>(
self,
) -> core::iter::Map<
I,
impl FnMut(<I>::Item) -> <<I>::Item as Pick<N>>::At,
>
where
Self::Item: Pick<N>,
{
self.map(|x| x.pick())
}
}