@@ -30,153 +30,110 @@ key_paths_core = "0.5"
3030### 1. CasePaths with Enums
3131
3232``` rust
33- use key_paths_core :: enum_keypath;
34- use key_paths_core :: EnumKeyPath ;
35-
36- #[derive(Debug )]
37- struct User {
38- id : u32 ,
39- name : String ,
40- }
41-
33+ use key_paths_core :: KeyPaths ;
4234#[derive(Debug )]
43- enum Status {
44- Active ( User ) ,
45- Inactive (()) ,
35+ enum Payment {
36+ Cash { amount : u32 } ,
37+ Card { number : String , cvv : String } ,
4638}
4739
4840fn main () {
49- let cp = enum_keypath! (Status :: Active (User ));
41+ let kp = KeyPaths :: writable_enum (
42+ | v | Payment :: Cash { amount : v },
43+ | p : & Payment | match p {
44+ Payment :: Cash { amount } => Some (amount ),
45+ _ => None ,
46+ },
47+ | p : & mut Payment | match p {
48+ Payment :: Cash { amount } => Some (amount ),
49+ _ => None ,
50+ },
5051
51- let status = Status :: Active (User {
52- id : 42 ,
53- name : " Charlie" . to_string (),
54- });
52+ );
5553
56- if let Some (u ) = cp . extract (& status ) {
57- println! (" Extracted user: {:?}" , u );
58- }
54+ let mut p = Payment :: Cash { amount : 10 };
5955
60- let new_status = cp . embed (User {
61- id : 99 ,
62- name : " Diana" . to_string (),
63- });
64- println! (" Embedded back: {:?}" , new_status );
56+ println! (" {:?}" , p );
57+
58+ if let Some (v ) = kp . get_mut (& mut p ) {
59+ * v = 34
60+ }
61+ println! (" {:?}" , p );
6562}
6663```
6764
6865---
6966
70- ### 2. Readable KeyPaths
67+ ### 2. Readable KeyPaths - helper macros wip
7168
7269``` rust
73- use key_paths_core :: {readable_keypath, ReadableKeyPath };
70+ use key_paths_core :: KeyPaths ;
71+
72+ #[derive(Debug )]
73+ struct Size {
74+ width : u32 ,
75+ height : u32 ,
76+ }
7477
7578#[derive(Debug )]
76- struct User {
79+ struct Rectangle {
80+ size : Size ,
7781 name : String ,
78- age : u32 ,
7982}
8083
8184fn main () {
82- let users = vec! [
83- User {
84- name : " Akash" . into (),
85- age : 25 ,
86- },
87- User {
88- name : " Soni" . into (),
89- age : 30 ,
85+ let mut rect = Rectangle {
86+ size : Size {
87+ width : 30 ,
88+ height : 50 ,
9089 },
91- User {
92- name : " Neha" . into (),
93- age : 20 ,
94- },
95- ];
96-
97- // Read-only keypath
98- // let name_key = ReadableKeyPath::new(|u: &User| &u.name);
99- let name_key = readable_keypath! (User , name );
100-
101- // Writable keypath
102- // let age_key = WritableKeyPath::new(
103- // |u: &User| &u.age,
104- // |u: &mut User| &mut u.age,
105- // );
106- // let age_key = writable_keypath!(User, age);
107-
108- println! (" Names:" );
109- for name in name_key . iter (& users ) {
110- println! (" {}" , name );
111- }
90+ name : " MyRect" . into (),
91+ };
92+
93+ let width_direct = KeyPaths :: readable (| r : & Rectangle | & r . size. width);
94+ println! (" Width: {:?}" , width_direct . get (& rect ));
11295}
11396```
11497
11598---
11699
117- ### 3. Writable KeyPaths
100+ ### 3. Writable KeyPaths - helper macros wip
118101
119102``` rust
120- use key_paths_core :: {writable_keypath, WritableKeyPath } ;
103+ use key_paths_core :: KeyPaths ;
121104
122105#[derive(Debug )]
123- struct User {
106+ struct Size {
107+ width : u32 ,
108+ height : u32 ,
109+ }
110+ #[derive(Debug )]
111+ struct Rectangle {
112+ size : Size ,
124113 name : String ,
125- age : u32 ,
126114}
127-
128115fn main () {
129- let mut users = vec! [
130- User {
131- name : " Akash" . into (),
132- age : 25 ,
133- },
134- User {
135- name : " Soni" . into (),
136- age : 30 ,
116+ let mut rect = Rectangle {
117+ size : Size {
118+ width : 30 ,
119+ height : 50 ,
137120 },
138- User {
139- name : " Neha" . into (),
140- age : 20 ,
141- },
142- ];
143-
144- // Read-only keypath
145- // let name_key = ReadableKeyPath::new(|u: &User| &u.name);
146- // let name_key = readable_keypath!(User, name);
147-
148- // Writable keypath
149- // let age_key = WritableKeyPath::new(
150- // |u: & User| & u.age,
151- // |u: &mut User| &mut u.age,
152- // );
153- let age_key = writable_keypath! (User , age );
154-
155- // println!("Names:");
156- // for name in name_key.iter(&users) {
157- // println!("{}", name);
158- // }
159-
160- println! (" Ages before:" );
161- for age in age_key . iter (& users ) {
162- println! (" {}" , age );
163- }
164-
165- // Mutate agesiter
166- for age in age_key . iter_mut (& mut users ) {
167- * age += 1 ;
168- }
169-
170- println! (" Ages after:" );
171- for age in age_key . iter (& mut users ) {
172- println! (" {}" , age );
121+ name : " MyRect" . into (),
122+ };
123+ let width_mut = KeyPaths :: writable (
124+ | r : & mut Rectangle | & mut r . size. width,
125+ );
126+ // Mutable
127+ if let Some (hp_mut ) = width_mut . get_mut (& mut rect ) {
128+ * hp_mut += 50 ;
173129 }
130+ println! (" Updated rectangle: {:?}" , rect );
174131}
175132```
176133
177134### 4. Composability and failablity
178135 ``` rust
179- use key_paths_core :: { FailableReadableKeyPath } ;
136+ use key_paths_core :: KeyPaths ;
180137
181138#[derive(Debug )]
182139struct Engine {
@@ -192,75 +149,96 @@ struct Garage {
192149}
193150
194151fn main () {
195- let garage = Garage {
152+ let mut garage = Garage {
196153 car : Some (Car {
197154 engine : Some (Engine { horsepower : 120 }),
198155 }),
199156 };
200157
201- let kp_car = FailableReadableKeyPath :: new (| g : & Garage | g . car. as_ref ());
202- let kp_engine = FailableReadableKeyPath :: new (| c : & Car | c . engine. as_ref ());
203- let kp_hp = FailableReadableKeyPath :: new (| e : & Engine | Some (& e . horsepower));
158+ let kp_car = KeyPaths :: failable_writable (| g : & mut Garage | g . car. as_mut ());
159+ let kp_engine = KeyPaths :: failable_writable (| c : & mut Car | c . engine. as_mut ());
160+ let kp_hp = KeyPaths :: failable_writable (| e : & mut Engine | Some (& mut e . horsepower));
204161
205162 // Compose: Garage -> Car -> Engine -> horsepower
206163 let kp = kp_car . compose (kp_engine ). compose (kp_hp );
207164
208- let kp2 = FailableReadableKeyPath :: new (| g : & Garage | {
209- g . car
210- . as_ref ()
211- . and_then (| c | c . engine. as_ref ())
212- . and_then (| e | Some (& e . horsepower))
213- });
214-
215- if let Some (hp ) = kp . try_get (& garage ) {
216- println! (" {hp:?}" );
217- }
218-
219- if let Some (hp ) = kp2 . try_get (& garage ) {
220- println! (" {hp:?}" );
165+ println! (" {garage:?}" );
166+ if let Some (hp ) = kp . get_mut (& mut garage ) {
167+ * hp = 200 ;
221168 }
222169
223170 println! (" {garage:?}" );
224171}
225172```
226173### 4. Mutablity
227174 ``` rust
228- use key_paths_core :: { FailableWritableKeyPath } ;
175+ use key_paths_core :: KeyPaths ;
229176
230177#[derive(Debug )]
231- struct Engine {
232- horsepower : u32 ,
178+ struct Size {
179+ width : u32 ,
180+ height : u32 ,
233181}
234182#[derive(Debug )]
235- struct Car {
236- engine : Option <Engine >,
183+ enum Color {
184+ Red ,
185+ Green ,
186+ Blue ,
187+ Other (RGBU8 ),
237188}
238189#[derive(Debug )]
239- struct Garage {
240- car : Option <Car >,
241- }
190+ struct RGBU8 (u8 , u8 , u8 );
242191
192+ #[derive(Debug )]
193+ struct ABox {
194+ name : String ,
195+ size : Size ,
196+ color : Color ,
197+ }
198+ #[derive(Debug )]
199+ struct Rectangle {
200+ size : Size ,
201+ name : String ,
202+ }
243203fn main () {
244- let mut garage = Garage {
245- car : Some (Car {
246- engine : Some (Engine { horsepower : 120 }),
247- }),
204+ let mut a_box = ABox {
205+ name : String :: from (" A box" ),
206+ size : Size {
207+ width : 10 ,
208+ height : 20 ,
209+ },
210+ color : Color :: Other (
211+ RGBU8 (10 , 20 , 30 )
212+ ),
248213 };
249214
250- let kp_car = FailableWritableKeyPath :: new (| g : & Garage | g . car. as_ref (), | g : & mut Garage | g . car. as_mut ());
251- let kp_engine = FailableWritableKeyPath :: new (| c : & Car | c . engine. as_ref (), | c : & mut Car | c . engine. as_mut ());
252- let kp_hp = FailableWritableKeyPath :: new (| e : & Engine | Some (& e . horsepower), | e : & mut Engine | Some (& mut e . horsepower));
253-
254- // Compose: Garage -> Car -> Engine -> horsepower
255- let kp = kp_car . compose (kp_engine ). compose (kp_hp );
215+ let color_kp : KeyPaths <ABox , Color > = KeyPaths :: failable_writable (| x : & mut ABox | Some (& mut x . color));
216+ let case_path = KeyPaths :: writable_enum (
217+ {
218+ | v | Color :: Other (v )
219+ },
220+ | p : & Color | match p {
221+ Color :: Other (rgb ) => Some (rgb ),
222+ _ => None ,
223+ },
224+ | p : & mut Color | match p {
225+ Color :: Other (rgb ) => Some (rgb ),
226+ _ => None ,
227+ },
256228
257- println! (" {garage:?}" );
258- if let Some (hp ) = kp . try_get_mut (& mut garage ) {
259- * hp = 200 ;
229+ );
230+
231+ println! (" {:?}" , a_box );
232+ let color_rgb_kp = color_kp . compose (case_path );
233+ if let Some (value ) = color_rgb_kp . get_mut (& mut a_box ) {
234+ * value = RGBU8 (0 , 0 , 0 );
260235 }
261-
262- println! (" {garage:?}" );
236+ println! (" {:?}" , a_box );
263237}
238+ /*
239+ ABox { name: "A box", size: Size { width: 10, height: 20 }, color: Other(RGBU8(10, 20, 30)) }
240+ ABox { name: "A box", size: Size { width: 10, height: 20 }, color: Other(RGBU8(0, 0, 0)) }
241+ */
264242```
265243
266244---
@@ -289,8 +267,7 @@ fn main() {
289267* [ ] ` compose ` support for combining multiple key paths.
290268* [ ] Derive macros for automatic KeyPath generation (Upcoming).
291269* [ ] Nested struct & enum traversal.
292- * [ ] Optional chaining (` User?.profile?.name ` ).
293-
270+ * [ ] Optional chaining (` User?.profile?.name ` ) with failable.
294271---
295272
296273## 📜 License
0 commit comments