@@ -20,7 +20,7 @@ Inspired by **Swift’s KeyPath / CasePath** system, this crate lets you work wi
2020
2121``` toml
2222[dependencies ]
23- key_paths_core = " 0.1 "
23+ key_paths_core = " 0.3 "
2424```
2525
2626---
@@ -70,9 +70,7 @@ fn main() {
7070### 2. Readable KeyPaths
7171
7272``` rust
73- use key_paths_core :: Readable ;
74- use key_paths_core :: ReadableKeyPath ;
75- use key_paths_core :: readable_keypath;
73+ use key_paths_core :: {readable_keypath, ReadableKeyPath };
7674
7775#[derive(Debug )]
7876struct User {
@@ -82,13 +80,31 @@ struct User {
8280
8381fn main () {
8482 let users = vec! [
85- User { name : " Akash" . into (), age : 25 },
86- User { name : " Soni" . into (), age : 30 },
87- User { name : " Neha" . into (), age : 20 },
83+ User {
84+ name : " Akash" . into (),
85+ age : 25 ,
86+ },
87+ User {
88+ name : " Soni" . into (),
89+ age : 30 ,
90+ },
91+ User {
92+ name : " Neha" . into (),
93+ age : 20 ,
94+ },
8895 ];
8996
97+ // Read-only keypath
98+ // let name_key = ReadableKeyPath::new(|u: &User| &u.name);
9099 let name_key = readable_keypath! (User , name );
91100
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+
92108 println! (" Names:" );
93109 for name in name_key . iter (& users ) {
94110 println! (" {}" , name );
@@ -101,10 +117,7 @@ fn main() {
101117### 3. Writable KeyPaths
102118
103119``` rust
104- use key_paths_core :: writable_keypath;
105- use key_paths_core :: WritableKeyPath ;
106- use key_paths_core :: Readable ;
107- use key_paths_core :: Writable ;
120+ use key_paths_core :: {writable_keypath, WritableKeyPath };
108121
109122#[derive(Debug )]
110123struct User {
@@ -114,29 +127,142 @@ struct User {
114127
115128fn main () {
116129 let mut users = vec! [
117- User { name : " Akash" . into (), age : 25 },
118- User { name : " Soni" . into (), age : 30 },
119- User { name : " Neha" . into (), age : 20 },
130+ User {
131+ name : " Akash" . into (),
132+ age : 25 ,
133+ },
134+ User {
135+ name : " Soni" . into (),
136+ age : 30 ,
137+ },
138+ User {
139+ name : " Neha" . into (),
140+ age : 20 ,
141+ },
120142 ];
121143
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+ // );
122153 let age_key = writable_keypath! (User , age );
123154
155+ // println!("Names:");
156+ // for name in name_key.iter(&users) {
157+ // println!("{}", name);
158+ // }
159+
124160 println! (" Ages before:" );
125161 for age in age_key . iter (& users ) {
126162 println! (" {}" , age );
127163 }
128164
165+ // Mutate agesiter
129166 for age in age_key . iter_mut (& mut users ) {
130167 * age += 1 ;
131168 }
132169
133170 println! (" Ages after:" );
134- for age in age_key . iter (& users ) {
171+ for age in age_key . iter (& mut users ) {
135172 println! (" {}" , age );
136173 }
137174}
138175```
139176
177+ ### 4. Composability and failablity
178+ ``` rust
179+ use key_paths_core :: {FailableReadableKeyPath };
180+
181+ #[derive(Debug )]
182+ struct Engine {
183+ horsepower : u32 ,
184+ }
185+ #[derive(Debug )]
186+ struct Car {
187+ engine : Option <Engine >,
188+ }
189+ #[derive(Debug )]
190+ struct Garage {
191+ car : Option <Car >,
192+ }
193+
194+ fn main () {
195+ let garage = Garage {
196+ car : Some (Car {
197+ engine : Some (Engine { horsepower : 120 }),
198+ }),
199+ };
200+
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));
204+
205+ // Compose: Garage -> Car -> Engine -> horsepower
206+ let kp = kp_car . compose (kp_engine ). compose (kp_hp );
207+
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:?}" );
221+ }
222+
223+ println! (" {garage:?}" );
224+ }
225+ ```
226+ ### 4. Mutablity
227+ ``` rust
228+ use key_paths_core :: {FailableWritableKeyPath };
229+
230+ #[derive(Debug )]
231+ struct Engine {
232+ horsepower : u32 ,
233+ }
234+ #[derive(Debug )]
235+ struct Car {
236+ engine : Option <Engine >,
237+ }
238+ #[derive(Debug )]
239+ struct Garage {
240+ car : Option <Car >,
241+ }
242+
243+ fn main () {
244+ let mut garage = Garage {
245+ car : Some (Car {
246+ engine : Some (Engine { horsepower : 120 }),
247+ }),
248+ };
249+
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 );
256+
257+ println! (" {garage:?}" );
258+ if let Some (hp ) = kp . try_get_mut (& mut garage ) {
259+ * hp = 200 ;
260+ }
261+
262+ println! (" {garage:?}" );
263+ }
264+ ```
265+
140266---
141267
142268## 🔗 Helpful Links & Resources
@@ -160,8 +286,8 @@ fn main() {
160286
161287## 🛠 Roadmap
162288
163- * [ ] ` zip ` support for combining multiple key paths (Upcoming) .
164- * [ ] Derive macros for automatic KeyPath generation.
289+ * [ ] ` compose ` support for combining multiple key paths.
290+ * [ ] Derive macros for automatic KeyPath generation (Upcoming) .
165291* [ ] Nested struct & enum traversal.
166292* [ ] Optional chaining (` User?.profile?.name ` ).
167293
0 commit comments