diff --git a/README.md b/README.md index 6d69c30..fbcc0a4 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ ergonomic lenses in rust it does *not* implement the operators, as it's not really a thing we can do in rust -does bringing lenses into rust actually make sense? probably not, but it was fun to implement +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 ## example diff --git a/src/combinations.rs b/src/combinations.rs index aaad29c..f409775 100644 --- a/src/combinations.rs +++ b/src/combinations.rs @@ -3,6 +3,7 @@ use crate::{ prisms::{Prism, PrismPreview}, traversals::{Traversal, TraversalOver, TraversalTraverse}, }; +use std::ops::Add; #[derive(Clone, Copy)] pub struct Combination(A, B); @@ -10,7 +11,7 @@ pub struct Combination(A, B); // additions // lens + lens -impl std::ops::Add> for Lens { +impl const Add> for Lens { type Output = Lens, Lens>>; fn add(self, rhs: Lens) -> Self::Output { @@ -18,7 +19,7 @@ impl std::ops::Add> for Lens { } } // prism + prism -impl std::ops::Add> for Prism { +impl const Add> for Prism { type Output = Prism, Prism>>; fn add(self, rhs: Prism) -> Self::Output { @@ -26,7 +27,7 @@ impl std::ops::Add> for Prism { } } // traversal + traversal -impl std::ops::Add> for Traversal { +impl const Add> for Traversal { type Output = Traversal, Traversal>>; fn add(self, rhs: Traversal) -> Self::Output { @@ -34,7 +35,7 @@ impl std::ops::Add> for Traversal { } } // traversal + lens -impl std::ops::Add> for Traversal { +impl const Add> for Traversal { type Output = Traversal, Traversal>>>; fn add(self, rhs: Lens) -> Self::Output { @@ -42,7 +43,7 @@ impl std::ops::Add> for Traversal { } } // lens + traversal -impl std::ops::Add> for Lens { +impl const Add> for Lens { type Output = Traversal>, Traversal>>; fn add(self, rhs: Traversal) -> Self::Output { @@ -50,7 +51,7 @@ impl std::ops::Add> for Lens { } } // traversal + prism -impl std::ops::Add> for Traversal { +impl const Add> for Traversal { type Output = Traversal, Traversal>>>; fn add(self, rhs: Prism) -> Self::Output { @@ -58,7 +59,7 @@ impl std::ops::Add> for Traversal { } } // prism + traversal -impl std::ops::Add> for Prism { +impl const Add> for Prism { type Output = Traversal>, Traversal>>; fn add(self, rhs: Traversal) -> Self::Output { @@ -66,7 +67,7 @@ impl std::ops::Add> for Prism { } } // lens + prism -impl std::ops::Add> for Lens { +impl const Add> for Lens { type Output = Traversal>, Traversal>>>; fn add(self, rhs: Prism) -> Self::Output { @@ -74,7 +75,7 @@ impl std::ops::Add> for Lens { } } // prism + traversal -impl std::ops::Add> for Prism { +impl const Add> for Prism { type Output = Traversal>, Traversal>>>; fn add(self, rhs: Lens) -> Self::Output { @@ -321,4 +322,17 @@ 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, Lens<_0Inner>>> = _0 + _0; + + let thing: ((i32, i32), i32) = ((1, 2), 3); + + let r: i32 = LENS(thing); + + assert_eq!(r, 1); + } } diff --git a/src/lenses/mod.rs b/src/lenses/mod.rs index 956bc78..6d4bfc6 100644 --- a/src/lenses/mod.rs +++ b/src/lenses/mod.rs @@ -1,22 +1,22 @@ -mod fields; +pub mod fields; -mod identity; +pub mod identity; pub use identity::id; -mod first; +pub mod first; pub use first::_0; -mod second; +pub mod second; pub use second::_1; -mod third; +pub mod third; pub use third::_2; -mod fourth; +pub mod fourth; pub use fourth::_3; -mod fifth; +pub mod fifth; pub use fifth::_4; -mod to; +pub mod to; pub use to::{to, to_from_boxed}; -mod lens; +pub mod lens; pub use lens::{lens, lens_from_boxed}; /// Wrapper type diff --git a/src/lib.rs b/src/lib.rs index 490e4ad..ba16e95 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(unboxed_closures, fn_traits)] +#![feature(unboxed_closures, fn_traits, const_trait_impl)] pub mod combinations; mod fns; diff --git a/src/prisms/mod.rs b/src/prisms/mod.rs index 58ffb6b..caeff7f 100644 --- a/src/prisms/mod.rs +++ b/src/prisms/mod.rs @@ -1,7 +1,7 @@ -mod result; +pub mod result; pub use result::{_Err, _Ok}; -mod option; +pub mod option; pub use option::{_None, _Some}; /// Wrapper type diff --git a/src/traversals/mod.rs b/src/traversals/mod.rs index c85dcd3..df57998 100644 --- a/src/traversals/mod.rs +++ b/src/traversals/mod.rs @@ -1,12 +1,12 @@ -mod both; +pub mod both; pub use both::both; -mod each; +pub mod each; pub use each::each; -mod head; +pub mod head; pub use head::_head; -mod tail; +pub mod tail; pub use tail::_tail; use crate::{ @@ -62,7 +62,7 @@ where // all lenses are traversals, so we can freely transform them into a traversal impl Lens { /// Returns this lens as a traversal - pub fn to_traversal(self) -> Traversal> { + pub const fn to_traversal(self) -> Traversal> { Traversal(self) } } @@ -98,7 +98,7 @@ where // all prisms are traversals, so we can freely transform them into a traversal impl Prism { /// Returns this lens as a traversal - pub fn to_traversal(self) -> Traversal> { + pub const fn to_traversal(self) -> Traversal> { Traversal(self) } }