photonix/lib.rs
1//! The intention of this crate is to provide optics for **accessing** and **updating** inner fields of nested immutable data structures (containers) in a convenient, efficient, functional, and Rust-friendly manner.
2//!
3//! Although **photonix** was inspired by functional lens libraries, it takes a different approach. Instead of _actual_ lenses with `get` and `set` (and `modify`) methods, here you have single-method type classes that provide flexibility in usage, and let the target data structures become their own lenses, which will obey the _lens laws_.
4//!
5//! This approach has some consequences. First of all, you won't need to store lens objects in memory. Second, in order to have the functionality, you won’t need to define and handle closures. Third, composition is achieved in a different way compared to traditional lenses (which rely on function composition).
6//!
7//! The **composition** feature is provided by additional traits defined in the [`composites`] module. By using composite traits, you can reach several levels deep in the implementing data structure. These traits have default implementation, so if you want to use them, all you need to do is write an empty impl block (or use the [`zoom!`] or [`zoom_all!`] macro).
8//!
9//! The real power of **photonix**, however, lies in its metaprogramming features. The crate comes with auto-derives ([`photonix_derive`]) for most of the base traits it defines. The implementations of the auto-derives avoid cloning data by default. Furthermore, the [`zoom!`] and [`zoom_all!`] macros can help you get the implementation of multiple composite traits in a concise, straightforward, and readable way.
10//!
11//! [`composites`]: focus/composites/index.html
12//! [`photonix_derive`]: https://docs.rs/photonix_derive/0.1.1/photonix_derive/
13//! [`zoom!`]: macro.zoom.html
14//! [`zoom_all!`]: macro.zoom_all.html
15//!
16//! # Examples
17//! A quick example (inspired by [`Monocle`]).
18//!
19//! [`Monocle`]: http://julien-truffaut.github.io/Monocle/
20//!
21//!```
22//! // We have a complex data structure
23//!
24//! # use photonix::*;
25//! #[derive(Get, GetRef, Set, Modify)]
26//! pub struct Employee { pub name: String, pub company: Company }
27//!
28//! #[derive(Get, GetRef, Set, Modify)]
29//! pub struct Company { pub name: String, pub address: Address }
30//!
31//! #[derive(Get, GetRef, Set, Modify)]
32//! pub struct Address { pub city: String, pub street: Street }
33//!
34//! #[derive(Get, GetRef, Set, Modify)]
35//! pub struct Street { pub number: u16, pub name: String }
36//!
37//! // We create an immutable variable
38//!
39//! let john = Employee { // Parent type
40//! name: String::from("john"),
41//! company: Company { // Level 1
42//! name: String::from("awesome inc"),
43//! address: Address { // Level 2
44//! city: String::from("london"),
45//! street: Street { // Level 3
46//! number: 23,
47//! name: String::from("high street"), // Level 4
48//! },
49//! },
50//! },
51//! };
52//!
53//! // Using zoom_all! is going to combine the derived Set, Get, GetRef, and Modify of each level
54//!
55//! zoom_all![Employee => Company => Address => Street => String];
56//!
57//! // Let's change the name of the street, which is at the fourth level
58//!
59//! let john_at_low_street = john.set_fourth(String::from("low street"));
60//!
61//! // We can retrieve the info by reference
62//!
63//! assert_eq!(
64//! "low street",
65//! john_at_low_street.get_ref_fourth().as_str()
66//! );
67//!
68//! // With modify, we can apply a function to the target field
69//!
70//! let john_at_high_again =
71//! john_at_low_street.modify_fourth(|street_name| street_name.replace("low", "high"));
72//!
73//! // We can retrieve the info by value as well
74//!
75//! assert_eq!(
76//! "high street",
77//! john_at_high_again.get_fourth().as_str()
78//! );
79//!
80//!```
81//!
82
83/// Type classes for getters and setters.
84pub mod focus;
85
86/// Relevant optics type class instances for common types (currently for `Option` only).
87pub mod implementations;
88
89pub use focus::{
90 *,
91 composites::*,
92};
93pub use implementations::*;
94pub use photonix_derive::*;