Crate lens_rs[−][src]
Overview
lens-rs
is a lens library for Rust, just like the package lens
for Haskell,
but here are no weird operators, grotesque symbols and confusing types.
Not only can lens-rs
get/set for fields of struct, but also variants of enum and items of collection.
It unifies the way to access to/construct with different nested substructures, providing Rusty-APIs.
Before use
Add the following in your Cargo.toml
[dependencies]
lens-rs = "0.3"
[package.metadata.inwelling]
lens-rs_generator = true
Add the following in your .rs files
use lens_rs::*;
Usage
Access substructures
visit field in struct:
let mut x = Foo { a: String::from(".a in Foo"), b: 0 }; assert_eq!(x.view_ref(optics!(a)), ".a in Foo"); *x.view_mut(optics!(b)) += 1; assert_eq!(x.view_ref(optics!(b)), &1)
visit variant in enum:
let mut x = Ok(0); *x.preview_ref(optics!(Ok))? += 1; assert_eq!(x.preview_ref(optics!(Ok))?, &1); assert_eq!(x.preview_ref(optics!(Err)), None);
visit items in collection:
let mut x = vec![1, 2, 3]; x.traverse_mut(optics!(_mapped)).into_iter().for_each(|x| *x += 1); assert_eq!(x.traverse_ref(optics!(_mapped)), vec![&2, &3, &4]); assert_eq!(x.view_ref(optics!([1])), &3);
build a structure:
let x = Review::review(optics!(Ok.Some), 1); assert_eq!(x, Ok(Some(1)));
Compose optics
macro optics!()
and Optics![]
is to compose optics:
let optics: Optics![_1.a.Some._mapped.[1]] = optics!(_1.a.Some._mapped.[1]); let x = (0, Foo { a: Some(vec![vec![1,2], vec![3,4]]), b: () }); assert_eq!(x.traverse(optics), vec![2, 4]);
Derive Optics
Derive Lens for fields to use .view_xx()
. (derive(Optic) is necessary)
#[derive(Lens)] struct Foo<A, B> { #[optic] a: A, // generate optics::a #[optic] b: B, // generate optics::b } #[derive(Lens)] struct Tuple<A, B>(#[optic] A, #[optic] B); // use optics::_0 or optics::_1 to access it
Derive Review/Prism for variants to use Review::review
/.preview_xx()
:
#[derive(Review, Prism)] enum Either<L, R> { #[optic] Left(L), // generate optics::Left #[optic] Right(R), // generate optics::Right }
Control the mutability:
#[derive(Debug, Lens)] struct Bar<C>{ #[optic(ref)] a: String, // can only take the immutable ref of .a by optics::a #[optic(mut)] b: i32, // can take the mutable ref of .b by optics::b #[optic] c: C // can move .c out by by optics::c }
A little row polymorphism
restrict a type has some fields:
fn with_field_a<T>(t: &T) -> &str where T: LensRef<Optics![a], String>, // T must have field a { t.view_ref(optics!(a)) } fn may_has_c<T>(t: T) -> Option<i32> where T: PrismRef<Optics![c], i32>, // T may have field c { Some(*t.preview_ref(optics!(c))?) } let foo = Foo { a: "this is Foo".to_string(), b: (), }; let bar = Bar { a: "this is Bar".to_string(), c: 0, }; assert_eq!(with_field_a(&foo), "this is Foo"); assert_eq!(with_field_a(&bar), "this is Bar"); assert_eq!(may_has_c(foo), None); assert_eq!(may_has_c(bar), Some(0)); assert_eq!(may_has_c(Left(0)), None); assert_eq!(may_has_c((1, 2, 3)), None);
Play with structx
Now, Lens
has implemented for structx
Add the following in your Cargo.toml
[dependencies]
lens-rs = { version = "0.3", features = [ "structx" ] }
structx = { version = "0.1", features = [ "lens-rs" ] }
[package.metadata.inwelling]
lens-rs_generator = true
structx = true
Enjoy it!
use structx::*; use lens_rs::*; let s1 = structx! { height: 1, width: 2 }; let s2 = structx! { height: 3, length: 4 }; assert_eq!(s1.view_ref(optics!(height)), &1); assert_eq!(s2.view_ref(optics!(height)), &3); assert_eq!(s1.preview_ref(optics!(width)), Some(&2)); assert_eq!(s2.preview_ref(optics!(width)), None);
Limitations
- can’t derive
Lens
for enum. - can’t derive
Prism
andReview
for the variant has more than one argument or has named field.
License
Under Apache License 2.0 or MIT License, at your will.
Re-exports
pub use traits::prism::*; |
pub use traits::review::*; |
pub use traits::traversal::*; |
Modules
optics | definitions of optics (including generated optic) |
traits | definitions of optics traits |
Macros
Optics | macro to compose optics |
optics | macro to compose optics |
Structs
_0 | build-in optics |
_1 | build-in optics |
_2 | build-in optics |
_3 | build-in optics |
_4 | build-in optics |
_5 | build-in optics |
_6 | build-in optics |
_7 | build-in optics |
_8 | build-in optics |
_9 | build-in optics |
_10 | build-in optics |
_11 | build-in optics |
_12 | build-in optics |
_13 | build-in optics |
_14 | build-in optics |
_15 | build-in optics |
_16 | build-in optics |
__ | build-in optics |
_both | build-in optics |
_box | build-in optics |
_ix | build-in optics |
_mapped | build-in optics |
_mut | build-in optics |
_ref | build-in optics |
Traits
Lens | the movable version of Lens |
LensMut | the mutable version of Lens |
LensRef | the immutable version of Lens |
Derive Macros
Lens | derive macro |
Prism | derive macro |
Review | derive macro |