bad-optics/src/traversals/each.rs

124 lines
3.4 KiB
Rust

use crate::{
traversals::{TraversalOver, TraversalTraverse},
Optics, OpticsTrait,
};
#[derive(Clone, Copy)]
pub struct EachInner;
#[allow(non_upper_case_globals)]
pub const each: Optics<EachInner> = Optics(EachInner);
impl OpticsTrait for EachInner {}
impl<T> TraversalTraverse<Vec<T>> for EachInner {
type Field = T;
fn traverse(&self, thing: Vec<T>) -> Vec<Self::Field> {
thing
}
}
impl<T> TraversalOver<Vec<T>> for EachInner {
fn over<F>(&self, thing: Vec<T>, f: F) -> Vec<T>
where
F: FnMut(Self::Field) -> Self::Field,
{
thing.into_iter().map(f).collect()
}
}
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
impl<T> TraversalTraverse<( $($t,)* )> for EachInner {
type Field = T;
fn traverse(&self, ( $($v,)* ): ($($t,)*)) -> Vec<Self::Field> {
vec![ $($v,)* ]
}
}
impl<T> TraversalOver<( $($t,)* )> for EachInner {
fn over<F>(
&self,
($($v,)*): ($($t,)*),
mut f: F
) -> ( $($t,)* )
where
F: FnMut(Self::Field) -> Self::Field
{
( $( f($v), )* )
}
}
impl<'a, T> TraversalTraverse<&'a ( $($t,)* )> for EachInner {
type Field = &'a T;
fn traverse(&self, ( $($v,)* ): &'a ($($t,)*)) -> Vec<Self::Field> {
vec![ $($v,)* ]
}
}
impl<'a, T> TraversalTraverse<&'a mut ( $($t,)* )> for EachInner {
type Field = &'a mut T;
fn traverse(&self, ( $($v,)* ): &'a mut ($($t,)*)) -> Vec<Self::Field> {
vec![ $($v,)* ]
}
}
};
}
make_tuples!(t, (t), (T));
make_tuples!(t, (t, u), (T, T));
make_tuples!(t, (t, u, v), (T, T, T));
make_tuples!(t, (t, u, v, w), (T, T, T, T));
make_tuples!(t, (t, u, v, w, x), (T, T, T, T, T));
make_tuples!(t, (t, u, v, w, x, y), (T, T, T, T, T, T));
make_tuples!(t, (t, u, v, w, x, y, z), (T, T, T, T, T, T, T));
// not doing more cause i'm lazy, open a pr if you need more :)
macro_rules! make_arrays {
($f:ident, $n:expr, [$( $v:ident ),*]) => {
impl<T> TraversalTraverse<[T; $n]> for EachInner {
type Field = T;
fn traverse(&self, [ $($v,)* ]: [T; $n]) -> Vec<Self::Field> {
vec![ $($v,)* ]
}
}
impl<T> TraversalOver<[T; $n]> for EachInner {
fn over<F>(
&self,
[ $($v,)* ]: [T; $n],
mut fun: F
) -> [T; $n]
where
F: FnMut(Self::Field) -> Self::Field
{
[$(fun($v),)*]
}
}
impl<'a, T> TraversalTraverse<&'a [T; $n]> for EachInner {
type Field = &'a T;
fn traverse(&self, [ $($v,)* ]: &'a [T; $n]) -> Vec<Self::Field> {
vec![ $($v,)* ]
}
}
impl<'a, T> TraversalTraverse<&'a mut [T; $n]> for EachInner {
type Field = &'a mut T;
fn traverse(&self, [ $($v,)* ]: &'a mut [T; $n]) -> Vec<Self::Field> {
vec![ $($v,)* ]
}
}
};
}
make_arrays!(t, 1, [t]);
make_arrays!(t, 2, [t, _a]);
make_arrays!(t, 3, [t, _a, _b]);
make_arrays!(t, 4, [t, _a, _b, _c]);
make_arrays!(t, 5, [t, _a, _b, _c, _d]);
make_arrays!(t, 6, [t, _a, _b, _c, _d, _e]);
make_arrays!(t, 7, [t, _a, _b, _c, _d, _e, _g]);