add set, rename first, add id

main
annieversary 2021-11-05 11:03:17 +00:00
parent e62f421fa6
commit 7bac8ee9ec
4 changed files with 54 additions and 11 deletions

View File

@ -2,7 +2,7 @@ use crate::{LensOver, LensView};
pub struct _0;
macro_rules! make {
macro_rules! make_tuples {
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
impl< $($t,)* > LensView<( $($t,)* )> for _0 {
type Field = T;
@ -11,7 +11,6 @@ macro_rules! make {
$f
}
}
impl< $($t,)* > LensOver<( $($t,)* )> for _0 {
fn over(
mut tup: ($($t,)*),
@ -21,6 +20,7 @@ macro_rules! make {
tup
}
}
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _0 {
type Field = &'a T;
@ -38,10 +38,10 @@ macro_rules! make {
};
}
make!(t, (t, _u), (T, U));
make!(t, (t, _u, _v), (T, U, V));
make!(t, (t, _u, _v, _w), (T, U, V, W));
make!(t, (t, _u, _v, _w, _x), (T, U, V, W, X));
make!(t, (t, _u, _v, _w, _x, _y), (T, U, V, W, X, Y));
make!(t, (t, _u, _v, _w, _x, _y, _z), (T, U, V, W, X, Y, Z));
make_tuples!(t, (t, _u), (T, U));
make_tuples!(t, (t, _u, _v), (T, U, V));
make_tuples!(t, (t, _u, _v, _w), (T, U, V, W));
make_tuples!(t, (t, _u, _v, _w, _x), (T, U, V, W, X));
make_tuples!(t, (t, _u, _v, _w, _x, _y), (T, U, V, W, X, Y));
make_tuples!(t, (t, _u, _v, _w, _x, _y, _z), (T, U, V, W, X, Y, Z));
// not doing more cause i'm lazy, open a pr if you need more :)

17
src/lenses/id.rs Normal file
View File

@ -0,0 +1,17 @@
use crate::{LensOver, LensView};
#[allow(non_camel_case_types)]
pub struct id;
impl<T> LensView<T> for T {
type Field = T;
fn view(thing: T) -> Self::Field {
thing
}
}
impl<T> LensOver<T> for T {
fn over(thing: T, f: &dyn Fn(Self::Field) -> Self::Field) -> T {
f(thing)
}
}

View File

@ -1,2 +1,4 @@
mod first_tuple;
pub use first_tuple::_0;
mod id;
pub use id::id;
mod first;
pub use first::_0;

View File

@ -6,11 +6,18 @@ pub trait LensView<T> {
pub trait LensOver<T>: LensView<T> {
fn over(thing: T, f: &dyn Fn(Self::Field) -> Self::Field) -> T;
fn set(thing: T, v: Self::Field) -> T {
Self::over(thing, &|_| v)
}
}
pub fn view<T, L: LensView<T>>(_lens: L, thing: T) -> L::Field {
L::view(thing)
}
pub fn set<T, L: LensOver<T>>(_lens: L, thing: T, v: L::Field) -> T {
L::set(thing, v)
}
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: &dyn Fn(L::Field) -> L::Field) -> T {
L::over(thing, f)
}
@ -19,6 +26,12 @@ pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: &dyn Fn(L::Field) -> L::Fi
// with one param it should be view, with two it should be over
// TODO add std::ops::Add to combine lenses
// TODO add second_from_tuple, etc
// TODO array traversals
// TODO make over work with changing types
pub mod lenses;
#[cfg(test)]
@ -56,7 +69,18 @@ mod tests {
}
#[test]
fn over_first_from_tuple_mut_works() {
fn set_first_from_tuple() {
let a = (1, 2);
let a = set(_0, a, 3);
assert_eq!(a, (3, 2));
let a = (1, 2);
let a = _0::set(a, 3);
assert_eq!(a, (3, 2));
}
#[test]
fn over_first_from_tuple() {
let a = (1, 2);
let a = over(_0, a, &|v| v + 1);
assert_eq!(a, (2, 2));