add _head and _tail traversals
This commit is contained in:
parent
16d7190a1d
commit
fa60e84466
3 changed files with 226 additions and 0 deletions
101
src/traversals/head.rs
Normal file
101
src/traversals/head.rs
Normal file
|
@ -0,0 +1,101 @@
|
|||
use crate::traversals::{Traversal, TraversalOver, TraversalTraverse};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct HeadInner;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const _head: Traversal<HeadInner> = Traversal(HeadInner);
|
||||
|
||||
macro_rules! make_tuples {
|
||||
(( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||
impl< $($t,)* > TraversalTraverse<( $($t,)* )> for HeadInner {
|
||||
type Field = T;
|
||||
|
||||
fn traverse(&self, ( head, $($v,)* ): ($($t,)*)) -> Vec<Self::Field> {
|
||||
vec![head]
|
||||
}
|
||||
}
|
||||
impl< $($t,)* > TraversalOver<( $($t,)* )> for HeadInner {
|
||||
fn over<F>(
|
||||
&self,
|
||||
(head, $($v,)*): ($($t,)*),
|
||||
mut f: F
|
||||
) -> ( $($t,)* )
|
||||
where
|
||||
F: FnMut(Self::Field) -> Self::Field
|
||||
{
|
||||
|
||||
( f(head), $($v,)* )
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, $($t,)* > TraversalTraverse<&'a ( $($t,)* )> for HeadInner {
|
||||
type Field = &'a T;
|
||||
|
||||
fn traverse(&self, (head, $($v,)* ): &'a ($($t,)*)) -> Vec<Self::Field> {
|
||||
vec![ head ]
|
||||
}
|
||||
}
|
||||
impl<'a, $($t,)* > TraversalTraverse<&'a mut ( $($t,)* )> for HeadInner {
|
||||
type Field = &'a mut T;
|
||||
|
||||
fn traverse(&self, (head, $($v,)* ): &'a mut ($($t,)*)) -> Vec<Self::Field> {
|
||||
vec![ head ]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_tuples!((), (T));
|
||||
make_tuples!((_u), (T, U));
|
||||
make_tuples!((_u, _v), (T, U, V));
|
||||
make_tuples!((_u, _v, _w), (T, U, V, W));
|
||||
make_tuples!((_u, _v, _w, _x), (T, U, V, W, X));
|
||||
make_tuples!((_u, _v, _w, _x, _y), (T, U, V, W, X, Y));
|
||||
make_tuples!((_u, _v, _w, _x, _y, _z), (T, U, V, W, X, Y, Z));
|
||||
|
||||
macro_rules! make_arrays {
|
||||
($n:expr, [$( $v:ident ),*]) => {
|
||||
impl<T> TraversalTraverse<[T; $n]> for HeadInner {
|
||||
type Field = T;
|
||||
|
||||
fn traverse(&self, [ head, $($v,)* ]: [T; $n]) -> Vec<Self::Field> {
|
||||
vec![head]
|
||||
}
|
||||
}
|
||||
impl<T> TraversalOver<[T; $n]> for HeadInner {
|
||||
fn over<F>(
|
||||
&self,
|
||||
[ head, $($v,)* ]: [T; $n],
|
||||
mut fun: F
|
||||
) -> [T; $n]
|
||||
where
|
||||
F: FnMut(Self::Field) -> Self::Field
|
||||
{
|
||||
[fun(head), $(($v),)*]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> TraversalTraverse<&'a [T; $n]> for HeadInner {
|
||||
type Field = &'a T;
|
||||
|
||||
fn traverse(&self, [head, $($v,)* ]: &'a [T; $n]) -> Vec<Self::Field> {
|
||||
vec![head]
|
||||
}
|
||||
}
|
||||
impl<'a, T> TraversalTraverse<&'a mut [T; $n]> for HeadInner {
|
||||
type Field = &'a mut T;
|
||||
|
||||
fn traverse(&self, [head, $($v,)* ]: &'a mut [T; $n]) -> Vec<Self::Field> {
|
||||
vec![head]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_arrays!(1, []);
|
||||
make_arrays!(2, [_a]);
|
||||
make_arrays!(3, [_a, _b]);
|
||||
make_arrays!(4, [_a, _b, _c]);
|
||||
make_arrays!(5, [_a, _b, _c, _d]);
|
||||
make_arrays!(6, [_a, _b, _c, _d, _e]);
|
||||
make_arrays!(7, [_a, _b, _c, _d, _e, _g]);
|
|
@ -4,6 +4,11 @@ pub use both::both;
|
|||
mod each;
|
||||
pub use each::each;
|
||||
|
||||
mod head;
|
||||
pub use head::_head;
|
||||
mod tail;
|
||||
pub use tail::_tail;
|
||||
|
||||
use crate::{
|
||||
lenses::{Lens, LensOver, LensView},
|
||||
prisms::{Prism, PrismPreview},
|
||||
|
@ -154,4 +159,26 @@ mod tests {
|
|||
let res = each(array, |v| v + 1);
|
||||
assert_eq!(res, [2, 3, 4, 5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn traverse_head_works_on_arrays() {
|
||||
let array = [1, 2, 3, 4];
|
||||
|
||||
let res = _head(array);
|
||||
assert_eq!(res, vec![1,]);
|
||||
|
||||
let res = _head(array, |v| v + 1);
|
||||
assert_eq!(res, [2, 2, 3, 4,]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn traverse_tail_works_on_arrays() {
|
||||
let array = [1, 2, 3, 4];
|
||||
|
||||
let res = _tail(array);
|
||||
assert_eq!(res, vec![2, 3, 4]);
|
||||
|
||||
let res = _tail(array, |v| v + 1);
|
||||
assert_eq!(res, [1, 3, 4, 5]);
|
||||
}
|
||||
}
|
||||
|
|
98
src/traversals/tail.rs
Normal file
98
src/traversals/tail.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use crate::traversals::{Traversal, TraversalOver, TraversalTraverse};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct TailInner;
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const _tail: Traversal<TailInner> = Traversal(TailInner);
|
||||
|
||||
macro_rules! make_tuples {
|
||||
(( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||
impl<T> TraversalTraverse<( $($t,)* )> for TailInner {
|
||||
type Field = T;
|
||||
|
||||
fn traverse(&self, ( _, $($v,)* ): ($($t,)*)) -> Vec<Self::Field> {
|
||||
vec![$($v,)*]
|
||||
}
|
||||
}
|
||||
impl<T> TraversalOver<( $($t,)* )> for TailInner {
|
||||
fn over<F>(
|
||||
&self,
|
||||
(head, $($v,)*): ($($t,)*),
|
||||
mut fun: F
|
||||
) -> ( $($t,)* )
|
||||
where
|
||||
F: FnMut(Self::Field) -> Self::Field
|
||||
{
|
||||
(head, $( fun($v) ,)*)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> TraversalTraverse<&'a ( $($t,)* )> for TailInner {
|
||||
type Field = &'a T;
|
||||
|
||||
fn traverse(&self, (_, $($v,)* ): &'a ($($t,)*)) -> Vec<Self::Field> {
|
||||
vec![ $($v,)* ]
|
||||
}
|
||||
}
|
||||
impl<'a, T> TraversalTraverse<&'a mut ( $($t,)* )> for TailInner {
|
||||
type Field = &'a mut T;
|
||||
|
||||
fn traverse(&self, (_, $($v,)* ): &'a mut ($($t,)*)) -> Vec<Self::Field> {
|
||||
vec![ $($v,)* ]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_tuples!((_u), (T, T));
|
||||
make_tuples!((_u, _v), (T, T, T));
|
||||
make_tuples!((_u, _v, _w), (T, T, T, T));
|
||||
make_tuples!((_u, _v, _w, _x), (T, T, T, T, T));
|
||||
make_tuples!((_u, _v, _w, _x, _y), (T, T, T, T, T, T));
|
||||
make_tuples!((_u, _v, _w, _x, _y, _z), (T, T, T, T, T, T, T));
|
||||
|
||||
macro_rules! make_arrays {
|
||||
($n:expr, [$( $v:ident ),*]) => {
|
||||
impl<T> TraversalTraverse<[T; $n]> for TailInner {
|
||||
type Field = T;
|
||||
|
||||
fn traverse(&self, [ _, $($v,)* ]: [T; $n]) -> Vec<Self::Field> {
|
||||
vec![$($v,)*]
|
||||
}
|
||||
}
|
||||
impl<T> TraversalOver<[T; $n]> for TailInner {
|
||||
fn over<F>(
|
||||
&self,
|
||||
[ head, $($v,)* ]: [T; $n],
|
||||
mut fun: F
|
||||
) -> [T; $n]
|
||||
where
|
||||
F: FnMut(Self::Field) -> Self::Field
|
||||
{
|
||||
[head, $(fun($v),)*]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> TraversalTraverse<&'a [T; $n]> for TailInner {
|
||||
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 TailInner {
|
||||
type Field = &'a mut T;
|
||||
|
||||
fn traverse(&self, [_, $($v,)* ]: &'a mut [T; $n]) -> Vec<Self::Field> {
|
||||
vec![$($v,)*]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_arrays!(2, [_a]);
|
||||
make_arrays!(3, [_a, _b]);
|
||||
make_arrays!(4, [_a, _b, _c]);
|
||||
make_arrays!(5, [_a, _b, _c, _d]);
|
||||
make_arrays!(6, [_a, _b, _c, _d, _e]);
|
||||
make_arrays!(7, [_a, _b, _c, _d, _e, _g]);
|
Loading…
Reference in a new issue