Compare commits

..

No commits in common. "c3d76f109f51efac96290326ff7ec3177f7c3ab0" and "16d7190a1de002475e0e0e9e817bc1e0e44cacc9" have entirely different histories.

14 changed files with 30 additions and 618 deletions

View file

@ -1,21 +1,13 @@
# bad optics
ergonomic lenses in rust
`bad-optics` implements the haskell concept of lenses, prisms, and traversals in rust
it does *not* implement the operators, as it's not really a thing we can do in rust
you will need nightly for this library to work, as it uses a bunch of unstable features. they're technically not *critical*, but i think not having them reduces the ergonomics too much
does bringing lenses into rust actually make sense? probably not, but it was fun to implement so who can say
ergonomic no-macro lenses for rust
## example
```rust
use bad_optics::{
lenses::{over, set},
prelude::*,
lenses::{_0, _1},
*,
};
fn main() {
@ -49,12 +41,6 @@ fn main() {
// you can also call the lens as a function to modify the value
let res = lens(a, |v| v + 1);
assert_eq!(res, ((1, 6), 3));
assert_eq!(res, ((1, 3), 3));
}
```
## how to use
bad-optics provides some of the lenses, prisms, and traversals defined in `lens`. i'm still trying to add more, so if there's one you need and it's missing from here, feel free to open a PR
if you don't know how lenses work, this is not really gonna be a tutorial, you should read [this](https://hackage.haskell.org/package/lens-tutorial-1.0.3/docs/Control-Lens-Tutorial.html) first instead. the general idea is that they are first-class getters and setters

View file

@ -1,4 +1,4 @@
use bad_optics::prelude::*;
use bad_optics::{lenses::*, prisms::*, traversals::*};
#[derive(Debug, PartialEq, Clone)]
struct MyStruct {

View file

@ -1,7 +1,4 @@
use bad_optics::{
lenses::{over, set},
prelude::*,
};
use bad_optics::lenses::*;
fn main() {
let a = ((1, 2), 3);

View file

@ -1,4 +1,4 @@
use bad_optics::prelude::*;
use bad_optics::lenses::*;
#[derive(Debug, PartialEq, Clone)]
struct MyStruct {

View file

@ -3,7 +3,6 @@ use crate::{
prisms::{Prism, PrismPreview},
traversals::{Traversal, TraversalOver, TraversalTraverse},
};
use std::ops::Add;
#[derive(Clone, Copy)]
pub struct Combination<A, B>(A, B);
@ -11,7 +10,7 @@ pub struct Combination<A, B>(A, B);
// additions
// lens + lens
impl<A, B> const Add<Lens<B>> for Lens<A> {
impl<A, B> std::ops::Add<Lens<B>> for Lens<A> {
type Output = Lens<Combination<Lens<A>, Lens<B>>>;
fn add(self, rhs: Lens<B>) -> Self::Output {
@ -19,7 +18,7 @@ impl<A, B> const Add<Lens<B>> for Lens<A> {
}
}
// prism + prism
impl<A, B> const Add<Prism<B>> for Prism<A> {
impl<A, B> std::ops::Add<Prism<B>> for Prism<A> {
type Output = Prism<Combination<Prism<A>, Prism<B>>>;
fn add(self, rhs: Prism<B>) -> Self::Output {
@ -27,7 +26,7 @@ impl<A, B> const Add<Prism<B>> for Prism<A> {
}
}
// traversal + traversal
impl<A, B> const Add<Traversal<B>> for Traversal<A> {
impl<A, B> std::ops::Add<Traversal<B>> for Traversal<A> {
type Output = Traversal<Combination<Traversal<A>, Traversal<B>>>;
fn add(self, rhs: Traversal<B>) -> Self::Output {
@ -35,7 +34,7 @@ impl<A, B> const Add<Traversal<B>> for Traversal<A> {
}
}
// traversal + lens
impl<A, B> const Add<Lens<B>> for Traversal<A> {
impl<A, B> std::ops::Add<Lens<B>> for Traversal<A> {
type Output = Traversal<Combination<Traversal<A>, Traversal<Lens<B>>>>;
fn add(self, rhs: Lens<B>) -> Self::Output {
@ -43,7 +42,7 @@ impl<A, B> const Add<Lens<B>> for Traversal<A> {
}
}
// lens + traversal
impl<A, B> const Add<Traversal<B>> for Lens<A> {
impl<A, B> std::ops::Add<Traversal<B>> for Lens<A> {
type Output = Traversal<Combination<Traversal<Lens<A>>, Traversal<B>>>;
fn add(self, rhs: Traversal<B>) -> Self::Output {
@ -51,7 +50,7 @@ impl<A, B> const Add<Traversal<B>> for Lens<A> {
}
}
// traversal + prism
impl<A, B> const Add<Prism<B>> for Traversal<A> {
impl<A, B> std::ops::Add<Prism<B>> for Traversal<A> {
type Output = Traversal<Combination<Traversal<A>, Traversal<Prism<B>>>>;
fn add(self, rhs: Prism<B>) -> Self::Output {
@ -59,7 +58,7 @@ impl<A, B> const Add<Prism<B>> for Traversal<A> {
}
}
// prism + traversal
impl<A, B> const Add<Traversal<B>> for Prism<A> {
impl<A, B> std::ops::Add<Traversal<B>> for Prism<A> {
type Output = Traversal<Combination<Traversal<Prism<A>>, Traversal<B>>>;
fn add(self, rhs: Traversal<B>) -> Self::Output {
@ -67,7 +66,7 @@ impl<A, B> const Add<Traversal<B>> for Prism<A> {
}
}
// lens + prism
impl<A, B> const Add<Prism<B>> for Lens<A> {
impl<A, B> std::ops::Add<Prism<B>> for Lens<A> {
type Output = Traversal<Combination<Traversal<Lens<A>>, Traversal<Prism<B>>>>;
fn add(self, rhs: Prism<B>) -> Self::Output {
@ -75,7 +74,7 @@ impl<A, B> const Add<Prism<B>> for Lens<A> {
}
}
// prism + traversal
impl<A, B> const Add<Lens<B>> for Prism<A> {
impl<A, B> std::ops::Add<Lens<B>> for Prism<A> {
type Output = Traversal<Combination<Traversal<Prism<A>>, Traversal<Lens<B>>>>;
fn add(self, rhs: Lens<B>) -> Self::Output {
@ -322,17 +321,4 @@ mod tests {
let res = t(thing, |v| v + 1);
assert_eq!(res, (Some(2), 2));
}
#[test]
fn can_combine_as_const() {
use crate::lenses::first::_0Inner;
use crate::lenses::Lens;
const LENS: Lens<super::Combination<Lens<_0Inner>, Lens<_0Inner>>> = _0 + _0;
let thing: ((i32, i32), i32) = ((1, 2), 3);
let r: i32 = LENS(thing);
assert_eq!(r, 1);
}
}

View file

@ -1,108 +0,0 @@
use crate::lenses::{Lens, LensOver, LensView};
#[derive(Clone, Copy)]
pub struct _4Inner;
pub const _4: Lens<_4Inner> = Lens(_4Inner);
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
impl< $($t,)* > LensView<( $($t,)* )> for _4Inner {
type Field = T;
fn view(&self, ( $($v,)* ): ($($t,)*)) -> Self::Field {
$f
}
}
impl< $($t,)* > LensOver<( $($t,)* )> for _4Inner {
fn over<F>(
&self,
mut tup: ($($t,)*),
f: F
) -> ( $($t,)* )
where
F: FnOnce(Self::Field) -> Self::Field
{
tup.4 = f(tup.4);
tup
}
}
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _4Inner {
type Field = &'a T;
fn view(&self, ( $($v,)* ): &'a ($($t,)*)) -> Self::Field {
$f
}
}
impl<'a, $($t,)* > LensView<&'a mut ( $($t,)* )> for _4Inner {
type Field = &'a mut T;
fn view(&self, ( $($v,)* ): &'a mut ($($t,)*)) -> Self::Field {
$f
}
}
};
}
make_tuples!(t, (_u, _v, _w, _x, t), (U, V, W, X, T));
make_tuples!(t, (_u, _v, _w, _x, t, _y), (U, V, W, X, T, Y));
make_tuples!(t, (_u, _v, _w, _x, t, _y, _z), (U, V, W, X, T, Y, Z));
make_tuples!(t, (_u, _v, _w, _x, t, _y, _z, _a), (U, V, W, X, T, Y, Z, A));
make_tuples!(
t,
(_u, _v, _w, _x, t, _y, _z, _a, _b),
(U, V, W, X, T, Y, Z, A, B)
);
make_tuples!(
t,
(_u, _v, _w, _x, t, _y, _z, _a, _b, _c),
(U, V, W, X, T, Y, Z, A, B, C)
);
// 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> LensView<[T; $n]> for _4Inner {
type Field = T;
fn view(&self, [ $($v,)* ]: [T; $n]) -> Self::Field {
$f
}
}
impl<T> LensOver<[T; $n]> for _4Inner {
fn over<F>(
&self,
tup: [T; $n],
fun: F
) -> [T; $n]
where
F: FnOnce(Self::Field) -> Self::Field
{
let [$($v,)*] = tup;
let $f = fun( $f );
[$($v,)*]
}
}
impl<'a, T> LensView<&'a [T; $n]> for _4Inner {
type Field = &'a T;
fn view(&self, [ $($v,)* ]: &'a [T; $n]) -> Self::Field {
$f
}
}
impl<'a, T> LensView<&'a mut [T; $n]> for _4Inner {
type Field = &'a mut T;
fn view(&self, [ $($v,)* ]: &'a mut [T; $n]) -> Self::Field {
$f
}
}
};
}
make_arrays!(t, 5, [_a, _b, _c, _d, t]);
make_arrays!(t, 6, [_a, _b, _c, _d, t, _e]);
make_arrays!(t, 7, [_a, _b, _c, _d, t, _e, _g]);
make_arrays!(t, 8, [_a, _b, _c, _d, t, _e, _g, _h]);
make_arrays!(t, 9, [_a, _b, _c, _d, t, _e, _g, _h, _i]);

View file

@ -1,110 +0,0 @@
use crate::lenses::{Lens, LensOver, LensView};
#[derive(Clone, Copy)]
pub struct _3Inner;
pub const _3: Lens<_3Inner> = Lens(_3Inner);
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
impl< $($t,)* > LensView<( $($t,)* )> for _3Inner {
type Field = T;
fn view(&self, ( $($v,)* ): ($($t,)*)) -> Self::Field {
$f
}
}
impl< $($t,)* > LensOver<( $($t,)* )> for _3Inner {
fn over<F>(
&self,
mut tup: ($($t,)*),
f: F
) -> ( $($t,)* )
where
F: FnOnce(Self::Field) -> Self::Field
{
tup.3 = f(tup.3);
tup
}
}
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _3Inner {
type Field = &'a T;
fn view(&self, ( $($v,)* ): &'a ($($t,)*)) -> Self::Field {
$f
}
}
impl<'a, $($t,)* > LensView<&'a mut ( $($t,)* )> for _3Inner {
type Field = &'a mut T;
fn view(&self, ( $($v,)* ): &'a mut ($($t,)*)) -> Self::Field {
$f
}
}
};
}
make_tuples!(t, (_u, _v, _w, t), (U, V, W, T));
make_tuples!(t, (_u, _v, _w, t, _x), (U, V, W, T, X));
make_tuples!(t, (_u, _v, _w, t, _x, _y), (U, V, W, T, X, Y));
make_tuples!(t, (_u, _v, _w, t, _x, _y, _z), (U, V, W, T, X, Y, Z));
make_tuples!(t, (_u, _v, _w, t, _x, _y, _z, _a), (U, V, W, T, X, Y, Z, A));
make_tuples!(
t,
(_u, _v, _w, t, _x, _y, _z, _a, _b),
(U, V, W, T, X, Y, Z, A, B)
);
make_tuples!(
t,
(_u, _v, _w, t, _x, _y, _z, _a, _b, _c),
(U, V, W, T, X, Y, Z, A, B, C)
);
// 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> LensView<[T; $n]> for _3Inner {
type Field = T;
fn view(&self, [ $($v,)* ]: [T; $n]) -> Self::Field {
$f
}
}
impl<T> LensOver<[T; $n]> for _3Inner {
fn over<F>(
&self,
tup: [T; $n],
fun: F
) -> [T; $n]
where
F: FnOnce(Self::Field) -> Self::Field
{
let [$($v,)*] = tup;
let $f = fun( $f );
[$($v,)*]
}
}
impl<'a, T> LensView<&'a [T; $n]> for _3Inner {
type Field = &'a T;
fn view(&self, [ $($v,)* ]: &'a [T; $n]) -> Self::Field {
$f
}
}
impl<'a, T> LensView<&'a mut [T; $n]> for _3Inner {
type Field = &'a mut T;
fn view(&self, [ $($v,)* ]: &'a mut [T; $n]) -> Self::Field {
$f
}
}
};
}
make_arrays!(t, 4, [_a, _b, _c, t]);
make_arrays!(t, 5, [_a, _b, _c, t, _d]);
make_arrays!(t, 6, [_a, _b, _c, t, _d, _e]);
make_arrays!(t, 7, [_a, _b, _c, t, _d, _e, _g]);
make_arrays!(t, 8, [_a, _b, _c, t, _d, _e, _g, _h]);
make_arrays!(t, 9, [_a, _b, _c, t, _d, _e, _g, _h, _i]);

View file

@ -1,22 +1,16 @@
pub mod fields;
mod fields;
pub mod identity;
mod identity;
pub use identity::id;
pub mod first;
mod first;
pub use first::_0;
pub mod second;
mod second;
pub use second::_1;
pub mod third;
pub use third::_2;
pub mod fourth;
pub use fourth::_3;
pub mod fifth;
pub use fifth::_4;
pub mod to;
mod to;
pub use to::{to, to_from_boxed};
pub mod lens;
mod lens;
pub use lens::{lens, lens_from_boxed};
/// Wrapper type

View file

@ -1,99 +0,0 @@
use crate::lenses::{Lens, LensOver, LensView};
#[derive(Clone, Copy)]
pub struct _2Inner;
pub const _2: Lens<_2Inner> = Lens(_2Inner);
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
impl< $($t,)* > LensView<( $($t,)* )> for _2Inner {
type Field = T;
fn view(&self, ( $($v,)* ): ($($t,)*)) -> Self::Field {
$f
}
}
impl< $($t,)* > LensOver<( $($t,)* )> for _2Inner {
fn over<F>(
&self,
mut tup: ($($t,)*),
f: F
) -> ( $($t,)* )
where
F: FnOnce(Self::Field) -> Self::Field
{
tup.2 = f(tup.2);
tup
}
}
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _2Inner {
type Field = &'a T;
fn view(&self, ( $($v,)* ): &'a ($($t,)*)) -> Self::Field {
$f
}
}
impl<'a, $($t,)* > LensView<&'a mut ( $($t,)* )> for _2Inner {
type Field = &'a mut T;
fn view(&self, ( $($v,)* ): &'a mut ($($t,)*)) -> Self::Field {
$f
}
}
};
}
make_tuples!(t, (_u, _v, t), (U, V, T));
make_tuples!(t, (_u, _v, t, _w), (U, V, T, W));
make_tuples!(t, (_u, _v, t, _w, _x), (U, V, T, W, X));
make_tuples!(t, (_u, _v, t, _w, _x, _y), (U, V, T, W, X, Y));
make_tuples!(t, (_u, _v, t, _w, _x, _y, _z), (U, V, T, W, X, Y, Z));
// 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> LensView<[T; $n]> for _2Inner {
type Field = T;
fn view(&self, [ $($v,)* ]: [T; $n]) -> Self::Field {
$f
}
}
impl<T> LensOver<[T; $n]> for _2Inner {
fn over<F>(
&self,
tup: [T; $n],
fun: F
) -> [T; $n]
where
F: FnOnce(Self::Field) -> Self::Field
{
let [$($v,)*] = tup;
let $f = fun( $f );
[$($v,)*]
}
}
impl<'a, T> LensView<&'a [T; $n]> for _2Inner {
type Field = &'a T;
fn view(&self, [ $($v,)* ]: &'a [T; $n]) -> Self::Field {
$f
}
}
impl<'a, T> LensView<&'a mut [T; $n]> for _2Inner {
type Field = &'a mut T;
fn view(&self, [ $($v,)* ]: &'a mut [T; $n]) -> Self::Field {
$f
}
}
};
}
make_arrays!(t, 3, [_a, _b, t]);
make_arrays!(t, 4, [_a, _b, t, _c]);
make_arrays!(t, 5, [_a, _b, t, _c, _d]);
make_arrays!(t, 6, [_a, _b, t, _c, _d, _e]);
make_arrays!(t, 7, [_a, _b, t, _c, _d, _e, _g]);

View file

@ -1,15 +1,7 @@
#![feature(unboxed_closures, fn_traits, const_trait_impl)]
#![feature(unboxed_closures, fn_traits)]
pub mod combinations;
mod combinations;
mod fns;
pub mod lenses;
pub mod prisms;
pub mod traversals;
pub mod prelude {
pub use crate::combinations::*;
pub use crate::lenses::*;
pub use crate::prisms::*;
pub use crate::traversals::*;
}

View file

@ -1,7 +1,7 @@
pub mod result;
mod result;
pub use result::{_Err, _Ok};
pub mod option;
mod option;
pub use option::{_None, _Some};
/// Wrapper type

View file

@ -1,101 +0,0 @@
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]);

View file

@ -1,14 +1,9 @@
pub mod both;
mod both;
pub use both::both;
pub mod each;
mod each;
pub use each::each;
pub mod head;
pub use head::_head;
pub mod tail;
pub use tail::_tail;
use crate::{
lenses::{Lens, LensOver, LensView},
prisms::{Prism, PrismPreview},
@ -62,7 +57,7 @@ where
// all lenses are traversals, so we can freely transform them into a traversal
impl<L> Lens<L> {
/// Returns this lens as a traversal
pub const fn to_traversal(self) -> Traversal<Lens<L>> {
pub fn to_traversal(self) -> Traversal<Lens<L>> {
Traversal(self)
}
}
@ -98,7 +93,7 @@ where
// all prisms are traversals, so we can freely transform them into a traversal
impl<L> Prism<L> {
/// Returns this lens as a traversal
pub const fn to_traversal(self) -> Traversal<Prism<L>> {
pub fn to_traversal(self) -> Traversal<Prism<L>> {
Traversal(self)
}
}
@ -159,26 +154,4 @@ 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]);
}
}

View file

@ -1,98 +0,0 @@
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]);