init
This commit is contained in:
commit
e62f421fa6
5 changed files with 127 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "bad-optics"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
47
src/lenses/first_tuple.rs
Normal file
47
src/lenses/first_tuple.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use crate::{LensOver, LensView};
|
||||||
|
|
||||||
|
pub struct _0;
|
||||||
|
|
||||||
|
macro_rules! make {
|
||||||
|
($f:ident, ( $( $v:ident ),* ), ( $( $t:ident ),* ) ) => {
|
||||||
|
impl< $($t,)* > LensView<( $($t,)* )> for _0 {
|
||||||
|
type Field = T;
|
||||||
|
|
||||||
|
fn view(( $($v,)* ): ($($t,)*)) -> Self::Field {
|
||||||
|
$f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl< $($t,)* > LensOver<( $($t,)* )> for _0 {
|
||||||
|
fn over(
|
||||||
|
mut tup: ($($t,)*),
|
||||||
|
f: &dyn Fn(Self::Field) -> Self::Field
|
||||||
|
) -> ( $($t,)* ) {
|
||||||
|
tup.0 = f(tup.0);
|
||||||
|
tup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a, $($t,)* > LensView<&'a ( $($t,)* )> for _0 {
|
||||||
|
type Field = &'a T;
|
||||||
|
|
||||||
|
fn view(( $($v,)* ): &'a ($($t,)*)) -> Self::Field {
|
||||||
|
$f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<'a, $($t,)* > LensView<&'a mut ( $($t,)* )> for _0 {
|
||||||
|
type Field = &'a mut T;
|
||||||
|
|
||||||
|
fn view(( $($v,)* ): &'a mut ($($t,)*)) -> Self::Field {
|
||||||
|
$f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
// not doing more cause i'm lazy, open a pr if you need more :)
|
2
src/lenses/mod.rs
Normal file
2
src/lenses/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
mod first_tuple;
|
||||||
|
pub use first_tuple::_0;
|
68
src/lib.rs
Normal file
68
src/lib.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
pub trait LensView<T> {
|
||||||
|
type Field;
|
||||||
|
|
||||||
|
fn view(thing: T) -> Self::Field;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LensOver<T>: LensView<T> {
|
||||||
|
fn over(thing: T, f: &dyn Fn(Self::Field) -> Self::Field) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view<T, L: LensView<T>>(_lens: L, thing: T) -> L::Field {
|
||||||
|
L::view(thing)
|
||||||
|
}
|
||||||
|
pub fn over<T, L: LensOver<T>>(_lens: L, thing: T, f: &dyn Fn(L::Field) -> L::Field) -> T {
|
||||||
|
L::over(thing, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add Fn implementation for lenses
|
||||||
|
// with one param it should be view, with two it should be over
|
||||||
|
// TODO add std::ops::Add to combine lenses
|
||||||
|
|
||||||
|
pub mod lenses;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{lenses::_0, *};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn view_first_from_tuple() {
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(view(_0, a), 1);
|
||||||
|
|
||||||
|
// you can call it both ways
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(_0::view(a), 1);
|
||||||
|
|
||||||
|
let a = (1, 2);
|
||||||
|
assert_eq!(view(_0, &a), &1);
|
||||||
|
|
||||||
|
let mut a = (1, 2);
|
||||||
|
assert_eq!(view(_0, &mut a), &mut 1);
|
||||||
|
|
||||||
|
let a = (1, 2, 3);
|
||||||
|
assert_eq!(view(_0, a), 1);
|
||||||
|
|
||||||
|
let a = (1, 2, 3);
|
||||||
|
assert_eq!(view(_0, &a), &1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn view_first_from_tuple_mut_works() {
|
||||||
|
let mut a = (1, 2);
|
||||||
|
*view(_0, &mut a) += 1;
|
||||||
|
|
||||||
|
assert_eq!(a, (2, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn over_first_from_tuple_mut_works() {
|
||||||
|
let a = (1, 2);
|
||||||
|
let a = over(_0, a, &|v| v + 1);
|
||||||
|
assert_eq!(a, (2, 2));
|
||||||
|
|
||||||
|
let a = (1, 2);
|
||||||
|
let a = _0::over(a, &|v| v + 1);
|
||||||
|
assert_eq!(a, (2, 2));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue