key_paths_core/
lib.rs

1use std::sync::{Arc, Mutex, RwLock};
2use std::rc::Rc;
3use std::cell::RefCell;
4
5#[cfg(feature = "tagged_core")]
6use tagged_core::Tagged;
7
8/// Trait for no-clone callback-based access to container types
9/// Provides methods to execute closures with references to values inside containers
10/// without requiring cloning of the values
11pub trait WithContainer<Root, Value> {
12    /// Execute a closure with a reference to the value inside an Arc
13    /// This avoids cloning by working with references directly
14    fn with_arc<F, R>(self, arc: &Arc<Root>, f: F) -> R
15    where
16        F: FnOnce(&Value) -> R;
17
18    /// Execute a closure with a reference to the value inside a Box
19    /// This avoids cloning by working with references directly
20    fn with_box<F, R>(self, boxed: &Box<Root>, f: F) -> R
21    where
22        F: FnOnce(&Value) -> R;
23
24    /// Execute a closure with a mutable reference to the value inside a Box
25    /// This avoids cloning by working with references directly
26    fn with_box_mut<F, R>(self, boxed: &mut Box<Root>, f: F) -> R
27    where
28        F: FnOnce(&mut Value) -> R;
29
30    /// Execute a closure with a reference to the value inside an Rc
31    /// This avoids cloning by working with references directly
32    fn with_rc<F, R>(self, rc: &Rc<Root>, f: F) -> R
33    where
34        F: FnOnce(&Value) -> R;
35
36    /// Execute a closure with a reference to the value inside a Result
37    /// This avoids cloning by working with references directly
38    fn with_result<F, R, E>(self, result: &Result<Root, E>, f: F) -> Option<R>
39    where
40        F: FnOnce(&Value) -> R;
41
42    /// Execute a closure with a mutable reference to the value inside a Result
43    /// This avoids cloning by working with references directly
44    fn with_result_mut<F, R, E>(self, result: &mut Result<Root, E>, f: F) -> Option<R>
45    where
46        F: FnOnce(&mut Value) -> R;
47
48    /// Execute a closure with a reference to the value inside an Option
49    /// This avoids cloning by working with references directly
50    fn with_option<F, R>(self, option: &Option<Root>, f: F) -> Option<R>
51    where
52        F: FnOnce(&Value) -> R;
53
54    /// Execute a closure with a mutable reference to the value inside an Option
55    /// This avoids cloning by working with references directly
56    fn with_option_mut<F, R>(self, option: &mut Option<Root>, f: F) -> Option<R>
57    where
58        F: FnOnce(&mut Value) -> R;
59
60    /// Execute a closure with a reference to the value inside a RefCell
61    /// This avoids cloning by working with references directly
62    fn with_refcell<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
63    where
64        F: FnOnce(&Value) -> R;
65
66    /// Execute a closure with a mutable reference to the value inside a RefCell
67    /// This avoids cloning by working with references directly
68    fn with_refcell_mut<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
69    where
70        F: FnOnce(&mut Value) -> R;
71
72    /// Execute a closure with a reference to the value inside a Tagged
73    /// This avoids cloning by working with references directly
74    #[cfg(feature = "tagged_core")]
75    fn with_tagged<F, R, Tag>(self, tagged: &Tagged<Root, Tag>, f: F) -> R
76    where
77        F: FnOnce(&Value) -> R;
78
79    /// Execute a closure with a reference to the value inside a Mutex
80    /// This avoids cloning by working with references while the guard is alive
81    fn with_mutex<F, R>(self, mutex: &Mutex<Root>, f: F) -> Option<R>
82    where
83        F: FnOnce(&Value) -> R;
84
85    /// Execute a closure with a mutable reference to the value inside a Mutex
86    /// This avoids cloning by working with references while the guard is alive
87    fn with_mutex_mut<F, R>(self, mutex: &mut Mutex<Root>, f: F) -> Option<R>
88    where
89        F: FnOnce(&mut Value) -> R;
90
91    /// Execute a closure with a reference to the value inside an RwLock
92    /// This avoids cloning by working with references while the guard is alive
93    fn with_rwlock<F, R>(self, rwlock: &RwLock<Root>, f: F) -> Option<R>
94    where
95        F: FnOnce(&Value) -> R;
96
97    /// Execute a closure with a mutable reference to the value inside an RwLock
98    /// This avoids cloning by working with references while the guard is alive
99    fn with_rwlock_mut<F, R>(self, rwlock: &mut RwLock<Root>, f: F) -> Option<R>
100    where
101        F: FnOnce(&mut Value) -> R;
102
103    /// Execute a closure with a reference to the value inside an Arc<RwLock<Root>>
104    /// This avoids cloning by working with references while the guard is alive
105    fn with_arc_rwlock<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
106    where
107        F: FnOnce(&Value) -> R;
108
109    /// Execute a closure with a mutable reference to the value inside an Arc<RwLock<Root>>
110    /// This avoids cloning by working with references while the guard is alive
111    fn with_arc_rwlock_mut<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
112    where
113        F: FnOnce(&mut Value) -> R;
114}
115
116#[derive(Clone)]
117/// Go to examples section to see the implementations
118///
119pub enum KeyPaths<Root, Value> {
120    Readable(Arc<dyn for<'a> Fn(&'a Root) -> &'a Value + Send + Sync>),
121    ReadableEnum {
122        extract: Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync>,
123        embed: Arc<dyn Fn(Value) -> Root + Send + Sync>,
124    },
125    FailableReadable(Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync>),
126
127    Writable(Arc<dyn for<'a> Fn(&'a mut Root) -> &'a mut Value + Send + Sync>),
128    FailableWritable(Arc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync>),
129    WritableEnum {
130        extract: Arc<dyn for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync>,
131        extract_mut: Arc<dyn for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync>,
132        embed: Arc<dyn Fn(Value) -> Root + Send + Sync>,
133    },
134
135
136    // New Owned KeyPath types (value semantics)
137    Owned(Arc<dyn Fn(Root) -> Value + Send + Sync>),
138    FailableOwned(Arc<dyn Fn(Root) -> Option<Value> + Send + Sync>),    
139}
140
141impl<Root, Value> KeyPaths<Root, Value> {
142    #[inline]
143    pub fn readable(get: impl for<'a> Fn(&'a Root) -> &'a Value + Send + Sync + 'static) -> Self {
144        Self::Readable(Arc::new(get))
145    }
146
147    #[inline]
148    pub fn writable(get_mut: impl for<'a> Fn(&'a mut Root) -> &'a mut Value + Send + Sync + 'static) -> Self {
149        Self::Writable(Arc::new(get_mut))
150    }
151
152    #[inline]
153    pub fn failable_readable(
154        get: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync + 'static,
155    ) -> Self {
156        Self::FailableReadable(Arc::new(get))
157    }
158
159    #[inline]
160    pub fn failable_writable(
161        get_mut: impl for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync + 'static,
162    ) -> Self {
163        Self::FailableWritable(Arc::new(get_mut))
164    }
165
166    #[inline]
167    pub fn readable_enum(
168        embed: impl Fn(Value) -> Root + Send + Sync + 'static,
169        extract: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync + 'static,
170    ) -> Self {
171        Self::ReadableEnum {
172            extract: Arc::new(extract),
173            embed: Arc::new(embed),
174        }
175    }
176
177    #[inline]
178    pub fn writable_enum(
179        embed: impl Fn(Value) -> Root + Send + Sync + 'static,
180        extract: impl for<'a> Fn(&'a Root) -> Option<&'a Value> + Send + Sync + 'static,
181        extract_mut: impl for<'a> Fn(&'a mut Root) -> Option<&'a mut Value> + Send + Sync + 'static,
182    ) -> Self {
183        Self::WritableEnum {
184            extract: Arc::new(extract),
185            embed: Arc::new(embed),
186            extract_mut: Arc::new(extract_mut),
187        }
188    }
189
190
191    // New Owned KeyPath constructors
192    #[inline]
193    pub fn owned(get: impl Fn(Root) -> Value + Send + Sync + 'static) -> Self {
194        Self::Owned(Arc::new(get))
195    }
196
197    #[inline]
198    pub fn failable_owned(get: impl Fn(Root) -> Option<Value> + Send + Sync + 'static) -> Self {
199        Self::FailableOwned(Arc::new(get))
200    }
201
202    #[inline]
203    pub fn owned_writable(get: impl Fn(Root) -> Value + Send + Sync + 'static) -> Self {
204        Self::Owned(Arc::new(get))
205    }
206    
207    #[inline]
208    pub fn failable_owned_writable(get: impl Fn(Root) -> Option<Value> + Send + Sync + 'static) -> Self {
209        Self::FailableOwned(Arc::new(get))
210    }
211
212    /// Extract values from a slice of references using this keypath
213    /// This is a convenience method for working with collections of references
214    /// 
215    /// Example:
216    /// ```rust
217    /// let name_path = Person::name_r();
218    /// let people = vec![&person1, &person2, &person3];
219    /// let names: Vec<&String> = name_path.extract_from_ref_slice(&people);
220    /// ```
221    #[inline]
222    pub fn extract_from_ref_slice<'a>(&self, slice: &'a [&Root]) -> Vec<&'a Value>
223    where
224        Root: 'static,
225        Value: 'static,
226    {
227        match self {
228            KeyPaths::Readable(f) => {
229                slice.iter().map(|item| f(item)).collect()
230            }
231            KeyPaths::FailableReadable(f) => {
232                slice.iter().filter_map(|item| f(item)).collect()
233            }
234            KeyPaths::ReadableEnum { extract, .. } => {
235                slice.iter().filter_map(|item| extract(item)).collect()
236            }
237            _ => panic!("extract_from_ref_slice only works with readable keypaths"),
238        }
239    }
240
241    /// Extract mutable values from a slice of mutable references using this keypath
242    /// This is a convenience method for working with collections of mutable references
243    /// 
244    /// Example:
245    /// ```rust
246    /// let name_path = Person::name_w();
247    /// let mut people = vec![&mut person1, &mut person2, &mut person3];
248    /// let names: Vec<&mut String> = name_path.extract_mut_from_ref_slice(&mut people);
249    /// ```
250    #[inline]
251    pub fn extract_mut_from_ref_slice<'a>(&self, slice: &'a mut [&mut Root]) -> Vec<&'a mut Value>
252    where
253        Root: 'static,
254        Value: 'static,
255    {
256        match self {
257            KeyPaths::Writable(f) => {
258                slice.iter_mut().map(|item| f(item)).collect()
259            }
260            KeyPaths::FailableWritable(f) => {
261                slice.iter_mut().filter_map(|item| f(item)).collect()
262            }
263            KeyPaths::WritableEnum { extract_mut, .. } => {
264                slice.iter_mut().filter_map(|item| extract_mut(item)).collect()
265            }
266            _ => panic!("extract_mut_from_ref_slice only works with writable keypaths"),
267        }
268    }
269}
270
271impl<Root, Value> KeyPaths<Root, Value> {
272    /// Get an immutable reference if possible
273    #[inline]
274    pub fn get<'a>(&'a self, root: &'a Root) -> Option<&'a Value> {
275        match self {
276            KeyPaths::Readable(f) => Some(f(root)),
277            KeyPaths::Writable(_) => None, // Writable requires mut
278            KeyPaths::FailableReadable(f) => f(root),
279            KeyPaths::FailableWritable(_) => None, // needs mut
280            KeyPaths::ReadableEnum { extract, .. } => extract(root),
281            KeyPaths::WritableEnum { extract, .. } => extract(root),
282            // New owned keypath types (don't work with references)
283            KeyPaths::Owned(_) => None, // Owned keypaths don't work with references
284            KeyPaths::FailableOwned(_) => None, // Owned keypaths don't work with references
285        }
286    }
287
288    /// Get an immutable reference when Root is itself a reference (&T)
289    /// This enables using keypaths with collections of references like Vec<&T>
290    #[inline]
291    pub fn get_ref<'a, 'b>(&'a self, root: &'b &Root) -> Option<&'b Value> 
292    where
293        'a: 'b,
294    {
295        match self {
296            KeyPaths::Readable(f) => Some(f(*root)),
297            KeyPaths::Writable(_) => None, // Writable requires mut
298            KeyPaths::FailableReadable(f) => f(*root),
299            KeyPaths::FailableWritable(_) => None, // needs mut
300            KeyPaths::ReadableEnum { extract, .. } => extract(*root),
301            KeyPaths::WritableEnum { extract, .. } => extract(*root),
302            // New owned keypath types (don't work with references)
303            KeyPaths::Owned(_) => None, // Owned keypaths don't work with references
304            KeyPaths::FailableOwned(_) => None, // Owned keypaths don't work with references
305        }
306    }
307
308    /// Get a mutable reference if possible
309    #[inline]
310    pub fn get_mut<'a>(&'a self, root: &'a mut Root) -> Option<&'a mut Value> {
311        match self {
312            KeyPaths::Readable(_) => None, // immutable only
313            KeyPaths::Writable(f) => Some(f(root)),
314            KeyPaths::FailableReadable(_) => None, // immutable only
315            KeyPaths::FailableWritable(f) => f(root),
316            KeyPaths::ReadableEnum { .. } => None, // immutable only
317            KeyPaths::WritableEnum { extract_mut, .. } => extract_mut(root),
318            // New owned keypath types (don't work with references)
319            KeyPaths::Owned(_) => None, // Owned keypaths don't work with references
320            KeyPaths::FailableOwned(_) => None, // Owned keypaths don't work with references
321        }
322    }
323
324    /// Get a mutable reference when Root is itself a mutable reference (&mut T)
325    /// This enables using writable keypaths with collections of mutable references
326    #[inline]
327    pub fn get_mut_ref<'a, 'b>(&'a self, root: &'b mut &mut Root) -> Option<&'b mut Value> 
328    where
329        'a: 'b,
330    {
331        match self {
332            KeyPaths::Readable(_) => None, // immutable only
333            KeyPaths::Writable(f) => Some(f(*root)),
334            KeyPaths::FailableReadable(_) => None, // immutable only
335            KeyPaths::FailableWritable(f) => f(*root),
336            KeyPaths::ReadableEnum { .. } => None, // immutable only
337            KeyPaths::WritableEnum { extract_mut, .. } => extract_mut(*root),
338            // New owned keypath types (don't work with references)
339            KeyPaths::Owned(_) => None, // Owned keypaths don't work with references
340            KeyPaths::FailableOwned(_) => None, // Owned keypaths don't work with references
341        }
342    }
343
344    // ===== Smart Pointer / Container Adapter Methods =====
345    // These methods create new keypaths that work with wrapped types
346    // Enables using KeyPaths<T, V> with Vec<Arc<T>>, Vec<Box<T>>, etc.
347
348    /// Adapt this keypath to work with Arc<Root>
349    /// Enables using KeyPaths<T, V> with collections like Vec<Arc<T>>
350    #[inline]
351    pub fn for_arc(self) -> KeyPaths<Arc<Root>, Value>
352    where
353        Root: 'static,
354        Value: 'static,
355    {
356        match self {
357            KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Arc<Root>| {
358                f(&**root)
359            })),
360            KeyPaths::Writable(_) => {
361                // Writable doesn't work with Arc (no mutable access)
362                panic!("Cannot create writable keypath for Arc (Arc is immutable)")
363            }
364            KeyPaths::FailableReadable(f) => {
365                KeyPaths::FailableReadable(Arc::new(move |root: &Arc<Root>| f(&**root)))
366            }
367            KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
368                extract: Arc::new(move |root: &Arc<Root>| extract(&**root)),
369                embed: Arc::new(move |value| Arc::new(embed(value))),
370            },
371            other => panic!("Unsupported keypath variant for Arc adapter: {:?}", kind_name(&other)),
372        }
373    }
374
375    /// Helper function to extract values from a slice using this keypath
376    /// This is useful when you have a slice &[T] and want to access fields via references
377    /// 
378    /// Example:
379    /// ```rust
380    /// let people = vec![Person { name: "Alice".to_string(), age: 30 }];
381    /// let names: Vec<&String> = Person::name_r().extract_from_slice(&people);
382    /// ```
383    #[inline]
384    pub fn extract_from_slice<'a>(&self, slice: &'a [Root]) -> Vec<&'a Value>
385    where
386        Root: 'static,
387        Value: 'static,
388    {
389        match self {
390            KeyPaths::Readable(f) => {
391                slice.iter().map(|item| f(item)).collect()
392            }
393            KeyPaths::FailableReadable(f) => {
394                slice.iter().filter_map(|item| f(item)).collect()
395            }
396            KeyPaths::ReadableEnum { extract, .. } => {
397                slice.iter().filter_map(|item| extract(item)).collect()
398            }
399            _ => panic!("extract_from_slice only works with readable keypaths"),
400        }
401    }
402
403    /// Helper function to extract values from an iterator using this keypath
404    /// This is useful when you have an iterator over &T and want to access fields
405    /// 
406    /// Example:
407    /// ```rust
408    /// let people = vec![Person { name: "Alice".to_string(), age: 30 }];
409    /// let names: Vec<&String> = Person::name_r().extract_from_iter(people.iter());
410    /// ```
411    #[inline]
412    pub fn extract_from_iter<'a, I>(&self, iter: I) -> Vec<&'a Value>
413    where
414        I: Iterator<Item = &'a Root>,
415        Root: 'static,
416        Value: 'static,
417    {
418        match self {
419            KeyPaths::Readable(f) => {
420                iter.map(|item| f(item)).collect()
421            }
422            KeyPaths::FailableReadable(f) => {
423                iter.filter_map(|item| f(item)).collect()
424            }
425            KeyPaths::ReadableEnum { extract, .. } => {
426                iter.filter_map(|item| extract(item)).collect()
427            }
428            _ => panic!("extract_from_iter only works with readable keypaths"),
429        }
430    }
431
432    /// Helper function to extract mutable values from a mutable slice using this keypath
433    /// This is useful when you have a mutable slice &mut [T] and want to access fields via mutable references
434    /// 
435    /// Example:
436    /// ```rust
437    /// let mut people = vec![Person { name: "Alice".to_string(), age: 30 }];
438    /// let names: Vec<&mut String> = Person::name_w().extract_mut_from_slice(&mut people);
439    /// ```
440    #[inline]
441    pub fn extract_mut_from_slice<'a>(&self, slice: &'a mut [Root]) -> Vec<&'a mut Value>
442    where
443        Root: 'static,
444        Value: 'static,
445    {
446        match self {
447            KeyPaths::Writable(f) => {
448                slice.iter_mut().map(|item| f(item)).collect()
449            }
450            KeyPaths::FailableWritable(f) => {
451                slice.iter_mut().filter_map(|item| f(item)).collect()
452            }
453            KeyPaths::WritableEnum { extract_mut, .. } => {
454                slice.iter_mut().filter_map(|item| extract_mut(item)).collect()
455            }
456            _ => panic!("extract_mut_from_slice only works with writable keypaths"),
457        }
458    }
459
460    /// Adapt this keypath to work with Box<Root>
461    /// Enables using KeyPaths<T, V> with collections like Vec<Box<T>>
462    #[inline]
463    pub fn for_box(self) -> KeyPaths<Box<Root>, Value>
464    where
465        Root: 'static,
466        Value: 'static,
467    {
468        match self {
469            KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Box<Root>| {
470                f(&**root)
471            })),
472            KeyPaths::Writable(f) => KeyPaths::Writable(Arc::new(move |root: &mut Box<Root>| {
473                f(&mut **root)
474            })),
475            KeyPaths::FailableReadable(f) => {
476                KeyPaths::FailableReadable(Arc::new(move |root: &Box<Root>| f(&**root)))
477            }
478            KeyPaths::FailableWritable(f) => {
479                KeyPaths::FailableWritable(Arc::new(move |root: &mut Box<Root>| f(&mut **root)))
480            }
481            KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
482                extract: Arc::new(move |root: &Box<Root>| extract(&**root)),
483                embed: Arc::new(move |value| Box::new(embed(value))),
484            },
485            KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
486                extract: Arc::new(move |root: &Box<Root>| extract(&**root)),
487                extract_mut: Arc::new(move |root: &mut Box<Root>| extract_mut(&mut **root)),
488                embed: Arc::new(move |value| Box::new(embed(value))),
489            },
490            other => panic!("Unsupported keypath variant for Box adapter: {:?}", kind_name(&other)),
491        }
492    }
493
494    /// Adapt this keypath to work with Rc<Root>
495    /// Enables using KeyPaths<T, V> with collections like Vec<Rc<T>>
496    #[inline]
497    pub fn for_rc(self) -> KeyPaths<Rc<Root>, Value>
498    where
499        Root: 'static,
500        Value: 'static,
501    {
502        match self {
503            KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Rc<Root>| {
504                f(&**root)
505            })),
506            KeyPaths::Writable(_) => {
507                // Writable doesn't work with Rc (no mutable access)
508                panic!("Cannot create writable keypath for Rc (Rc is immutable)")
509            }
510            KeyPaths::FailableReadable(f) => {
511                KeyPaths::FailableReadable(Arc::new(move |root: &Rc<Root>| f(&**root)))
512            }
513            KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
514                extract: Arc::new(move |root: &Rc<Root>| extract(&**root)),
515                embed: Arc::new(move |value| Rc::new(embed(value))),
516            },
517            other => panic!("Unsupported keypath variant for Rc adapter: {:?}", kind_name(&other)),
518        }
519    }
520
521    /// Adapt this keypath to work with Result<Root, E>
522    /// Enables using KeyPaths<T, V> with Result types
523    /// Note: This creates a FailableReadable keypath since Result can be Err
524    #[inline]
525    pub fn for_result<E>(self) -> KeyPaths<Result<Root, E>, Value>
526    where
527        Root: 'static,
528        Value: 'static,
529        E: 'static,
530    {
531        match self {
532            KeyPaths::Readable(f) => KeyPaths::FailableReadable(Arc::new(move |root: &Result<Root, E>| {
533                root.as_ref().ok().map(|r| f(r))
534            })),
535            KeyPaths::Writable(f) => KeyPaths::FailableWritable(Arc::new(move |root: &mut Result<Root, E>| {
536                root.as_mut().ok().map(|r| f(r))
537            })),
538            KeyPaths::FailableReadable(f) => {
539                KeyPaths::FailableReadable(Arc::new(move |root: &Result<Root, E>| {
540                    root.as_ref().ok().and_then(|r| f(r))
541                }))
542            }
543            KeyPaths::FailableWritable(f) => {
544                KeyPaths::FailableWritable(Arc::new(move |root: &mut Result<Root, E>| {
545                    root.as_mut().ok().and_then(|r| f(r))
546                }))
547            }
548            KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
549                extract: Arc::new(move |root: &Result<Root, E>| {
550                    root.as_ref().ok().and_then(|r| extract(r))
551                }),
552                embed: Arc::new(move |value| Ok(embed(value))),
553            },
554            KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
555                extract: Arc::new(move |root: &Result<Root, E>| {
556                    root.as_ref().ok().and_then(|r| extract(r))
557                }),
558                extract_mut: Arc::new(move |root: &mut Result<Root, E>| {
559                    root.as_mut().ok().and_then(|r| extract_mut(r))
560                }),
561                embed: Arc::new(move |value| Ok(embed(value))),
562            },
563            other => panic!("Unsupported keypath variant for Result adapter: {:?}", kind_name(&other)),
564        }
565    }
566
567    /// Adapt this keypath to work with Option<Root>
568    /// Enables using KeyPaths<T, V> with Option types
569    /// Note: This creates a FailableReadable/FailableWritable keypath since Option can be None
570    #[inline]
571    pub fn for_option(self) -> KeyPaths<Option<Root>, Value>
572    where
573        Root: 'static,
574        Value: 'static,
575    {
576        match self {
577            KeyPaths::Readable(f) => KeyPaths::FailableReadable(Arc::new(move |root: &Option<Root>| {
578                root.as_ref().map(|r| f(r))
579            })),
580            KeyPaths::Writable(f) => KeyPaths::FailableWritable(Arc::new(move |root: &mut Option<Root>| {
581                root.as_mut().map(|r| f(r))
582            })),
583            KeyPaths::FailableReadable(f) => {
584                KeyPaths::FailableReadable(Arc::new(move |root: &Option<Root>| {
585                    root.as_ref().and_then(|r| f(r))
586                }))
587            }
588            KeyPaths::FailableWritable(f) => {
589                KeyPaths::FailableWritable(Arc::new(move |root: &mut Option<Root>| {
590                    root.as_mut().and_then(|r| f(r))
591                }))
592            }
593            KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
594                extract: Arc::new(move |root: &Option<Root>| {
595                    root.as_ref().and_then(|r| extract(r))
596                }),
597                embed: Arc::new(move |value| Some(embed(value))),
598            },
599            KeyPaths::WritableEnum { extract, extract_mut, embed } => KeyPaths::WritableEnum {
600                extract: Arc::new(move |root: &Option<Root>| {
601                    root.as_ref().and_then(|r| extract(r))
602                }),
603                extract_mut: Arc::new(move |root: &mut Option<Root>| {
604                    root.as_mut().and_then(|r| extract_mut(r))
605                }),
606                embed: Arc::new(move |value| Some(embed(value))),
607            },
608            other => panic!("Unsupported keypath variant for Option adapter: {:?}", kind_name(&other)),
609        }
610    }
611
612    /// Adapt this keypath to work with Arc<RwLock<Root>>
613    /// Enables using KeyPaths<T, V> with Arc<RwLock<T>> containers
614    /// Note: This creates a FailableOwned keypath since RwLock access can fail and we need to clone values
615    #[inline]
616    pub fn for_arc_rwlock(self) -> KeyPaths<Arc<RwLock<Root>>, Value>
617    where
618        Root: 'static,
619        Value: Clone + 'static,
620    {
621        match self {
622            KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<RwLock<Root>>| {
623                let guard = root.read().ok()?;
624                Some(f(&*guard).clone())
625            })),
626            KeyPaths::Writable(_) => {
627                // Writable doesn't work with Arc<RwLock> (Arc is immutable, need write guard)
628                panic!("Cannot create writable keypath for Arc<RwLock> (use with_arc_rwlock_mut instead)")
629            }
630            KeyPaths::FailableReadable(f) => {
631                KeyPaths::FailableOwned(Arc::new(move |root: Arc<RwLock<Root>>| {
632                    let guard = root.read().ok()?;
633                    f(&*guard).map(|v| v.clone())
634                }))
635            }
636            KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<RwLock<Root>>| {
637                let guard = root.read().ok()?;
638                extract(&*guard).map(|v| v.clone())
639            })),
640            other => panic!("Unsupported keypath variant for Arc<RwLock> adapter: {:?}", kind_name(&other)),
641        }
642    }
643
644    /// Adapt this keypath to work with Arc<Mutex<Root>>
645    /// Enables using KeyPaths<T, V> with Arc<Mutex<T>> containers
646    /// Note: This creates a FailableOwned keypath since Mutex access can fail and we need to clone values
647    #[inline]
648    pub fn for_arc_mutex(self) -> KeyPaths<Arc<Mutex<Root>>, Value>
649    where
650        Root: 'static,
651        Value: Clone + 'static,
652    {
653        match self {
654            KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<Mutex<Root>>| {
655                let guard = root.lock().ok()?;
656                Some(f(&*guard).clone())
657            })),
658            KeyPaths::Writable(_) => {
659                // Writable doesn't work with Arc<Mutex> (Arc is immutable, need write guard)
660                panic!("Cannot create writable keypath for Arc<Mutex> (use with_arc_mutex_mut instead)")
661            }
662            KeyPaths::FailableReadable(f) => {
663                KeyPaths::FailableOwned(Arc::new(move |root: Arc<Mutex<Root>>| {
664                    let guard = root.lock().ok()?;
665                    f(&*guard).map(|v| v.clone())
666                }))
667            }
668            KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<Mutex<Root>>| {
669                let guard = root.lock().ok()?;
670                extract(&*guard).map(|v| v.clone())
671            })),
672            other => panic!("Unsupported keypath variant for Arc<Mutex> adapter: {:?}", kind_name(&other)),
673        }
674    }
675
676    /// Adapt this keypath to work with Arc<parking_lot::Mutex<Root>>
677    /// Enables using KeyPaths<T, V> with Arc<parking_lot::Mutex<T>> containers
678    /// Note: This creates a FailableOwned keypath since Mutex access can fail and we need to clone values
679    /// Requires the "parking_lot" feature to be enabled
680    #[cfg(feature = "parking_lot")]
681    #[inline]
682    pub fn for_arc_parking_mutex(self) -> KeyPaths<Arc<parking_lot::Mutex<Root>>, Value>
683    where
684        Root: 'static,
685        Value: Clone + 'static,
686    {
687        match self {
688            KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
689                let guard = root.lock();
690                Some(f(&*guard).clone())
691            })),
692            KeyPaths::Writable(_) => {
693                // Writable doesn't work with Arc<parking_lot::Mutex> (Arc is immutable, need write guard)
694                panic!("Cannot create writable keypath for Arc<parking_lot::Mutex> (use with_arc_parking_mutex_mut instead)")
695            }
696            KeyPaths::FailableReadable(f) => {
697                KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
698                    let guard = root.lock();
699                    f(&*guard).map(|v| v.clone())
700                }))
701            }
702            KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::Mutex<Root>>| {
703                let guard = root.lock();
704                extract(&*guard).map(|v| v.clone())
705            })),
706            other => panic!("Unsupported keypath variant for Arc<parking_lot::Mutex> adapter: {:?}", kind_name(&other)),
707        }
708    }
709
710    /// Adapt this keypath to work with Arc<parking_lot::RwLock<Root>>
711    /// Enables using KeyPaths<T, V> with Arc<parking_lot::RwLock<T>> containers
712    /// Note: This creates a FailableOwned keypath since RwLock access can fail and we need to clone values
713    /// Requires the "parking_lot" feature to be enabled
714    #[cfg(feature = "parking_lot")]
715    #[inline]
716    pub fn for_arc_parking_rwlock(self) -> KeyPaths<Arc<parking_lot::RwLock<Root>>, Value>
717    where
718        Root: 'static,
719        Value: Clone + 'static,
720    {
721        match self {
722            KeyPaths::Readable(f) => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
723                let guard = root.read();
724                Some(f(&*guard).clone())
725            })),
726            KeyPaths::Writable(_) => {
727                // Writable doesn't work with Arc<parking_lot::RwLock> (Arc is immutable, need write guard)
728                panic!("Cannot create writable keypath for Arc<parking_lot::RwLock> (use with_arc_parking_rwlock_mut instead)")
729            }
730            KeyPaths::FailableReadable(f) => {
731                KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
732                    let guard = root.read();
733                    f(&*guard).map(|v| v.clone())
734                }))
735            }
736            KeyPaths::ReadableEnum { extract, embed: _ } => KeyPaths::FailableOwned(Arc::new(move |root: Arc<parking_lot::RwLock<Root>>| {
737                let guard = root.read();
738                extract(&*guard).map(|v| v.clone())
739            })),
740            other => panic!("Unsupported keypath variant for Arc<parking_lot::RwLock> adapter: {:?}", kind_name(&other)),
741        }
742    }
743
744    /// Adapt a keypath to work with Tagged<Tag, Root>
745    /// Returns a new KeyPaths instance that can work with Tagged values
746    /// Note: Tagged<T, Tag> where T is the actual value and Tag is a zero-sized phantom type
747    /// Tagged only implements Deref, not DerefMut, so writable keypaths are not supported
748    #[cfg(feature = "tagged_core")]
749    #[inline]
750    pub fn for_tagged<Tag>(self) -> KeyPaths<Tagged<Root, Tag>, Value>
751    where
752        Root: Clone + 'static,
753        Value: 'static,
754        Tag: 'static,
755    {
756        match self {
757            KeyPaths::Readable(f) => KeyPaths::Readable(Arc::new(move |root: &Tagged<Root, Tag>| {
758                f(&**root)
759            })),
760            KeyPaths::Writable(_) => {
761                panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
762            }
763            KeyPaths::FailableReadable(f) => KeyPaths::FailableReadable(Arc::new(move |root: &Tagged<Root, Tag>| {
764                f(&**root)
765            })),
766            KeyPaths::FailableWritable(_) => {
767                panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
768            }
769            KeyPaths::ReadableEnum { extract, embed } => KeyPaths::ReadableEnum {
770                extract: Arc::new(move |root: &Tagged<Root, Tag>| {
771                    extract(&**root)
772                }),
773                embed: Arc::new(move |value: Value| {
774                    Tagged::new(embed(value))
775                }),
776            },
777            KeyPaths::WritableEnum { .. } => {
778                panic!("Tagged does not support writable keypaths (Tagged only implements Deref, not DerefMut)")
779            }
780            KeyPaths::Owned(f) => KeyPaths::Owned(Arc::new(move |root: Tagged<Root, Tag>| {
781                // Tagged consumes itself and returns the inner value by cloning
782                f((*root).clone())
783            })),
784            KeyPaths::FailableOwned(f) => KeyPaths::FailableOwned(Arc::new(move |root: Tagged<Root, Tag>| {
785                f((*root).clone())
786            })),
787        }
788    }
789
790    // ===== WithContainer Trait Implementation =====
791    // All with_* methods are now implemented via the WithContainer trait
792
793    pub fn embed(&self, value: Value) -> Option<Root>
794    where
795        Value: Clone,
796    {
797        match self {
798            KeyPaths::ReadableEnum { embed, .. } => Some(embed(value)),
799            _ => None,
800        }
801    }
802
803    pub fn embed_mut(&self, value: Value) -> Option<Root>
804    where
805        Value: Clone,
806    {
807        match self {
808            KeyPaths::WritableEnum { embed, .. } => Some(embed(value)),
809            _ => None,
810        }
811    }
812
813
814    // ===== Owned KeyPath Accessor Methods =====
815
816    /// Get an owned value (primary method for owned keypaths)
817    #[inline]
818    pub fn get_owned(self, root: Root) -> Value {
819        match self {
820            KeyPaths::Owned(f) => f(root),
821            _ => panic!("get_owned only works with owned keypaths"),
822        }
823    }
824
825    /// Get an owned value with failable access
826    #[inline]
827    pub fn get_failable_owned(self, root: Root) -> Option<Value> {
828        match self {
829            KeyPaths::FailableOwned(f) => f(root),
830            _ => panic!("get_failable_owned only works with failable owned keypaths"),
831        }
832    }
833
834    /// Iter over immutable references if `Value: IntoIterator`
835    pub fn iter<'a, T>(&'a self, root: &'a Root) -> Option<<&'a Value as IntoIterator>::IntoIter>
836    where
837        &'a Value: IntoIterator<Item = &'a T>,
838        T: 'a,
839    {
840        self.get(root).map(|v| v.into_iter())
841    }
842
843    /// Iter over mutable references if `&mut Value: IntoIterator`
844    pub fn iter_mut<'a, T>(
845        &'a self,
846        root: &'a mut Root,
847    ) -> Option<<&'a mut Value as IntoIterator>::IntoIter>
848    where
849        &'a mut Value: IntoIterator<Item = &'a mut T>,
850        T: 'a,
851    {
852        self.get_mut(root).map(|v| v.into_iter())
853    }
854
855    /// Consume root and iterate if `Value: IntoIterator`
856    #[inline]
857    pub fn into_iter<T>(self, root: Root) -> Option<<Value as IntoIterator>::IntoIter>
858    where
859        Value: IntoIterator<Item = T> + Clone,
860    {
861        match self {
862            KeyPaths::Readable(f) => Some(f(&root).clone().into_iter()), // requires Clone
863            KeyPaths::Writable(_) => None,
864            KeyPaths::FailableReadable(f) => f(&root).map(|v| v.clone().into_iter()),
865            KeyPaths::FailableWritable(_) => None,
866            KeyPaths::ReadableEnum { extract, .. } => extract(&root).map(|v| v.clone().into_iter()),
867            KeyPaths::WritableEnum { extract, .. } => extract(&root).map(|v| v.clone().into_iter()),
868            // New owned keypath types
869            KeyPaths::Owned(f) => Some(f(root).into_iter()),
870            KeyPaths::FailableOwned(f) => f(root).map(|v| v.into_iter()),
871        }
872    }
873}
874
875// ===== WithContainer Trait Implementation =====
876impl<Root, Value> WithContainer<Root, Value> for KeyPaths<Root, Value> {
877    /// Execute a closure with a reference to the value inside an Arc
878    /// This avoids cloning by working with references directly
879    #[inline]
880    fn with_arc<F, R>(self, arc: &Arc<Root>, f: F) -> R
881    where
882        F: FnOnce(&Value) -> R,
883    {
884        match self {
885            KeyPaths::Readable(get) => f(get(&**arc)),
886            KeyPaths::FailableReadable(get) => {
887                if let Some(value) = get(&**arc) {
888                    f(value)
889                } else {
890                    panic!("FailableReadable keypath returned None for Arc")
891                }
892            }
893            _ => panic!("with_arc only works with readable keypaths"),
894        }
895    }
896
897    /// Execute a closure with a reference to the value inside a Box
898    /// This avoids cloning by working with references directly
899    #[inline]
900    fn with_box<F, R>(self, boxed: &Box<Root>, f: F) -> R
901    where
902        F: FnOnce(&Value) -> R,
903    {
904        match self {
905            KeyPaths::Readable(get) => f(get(&**boxed)),
906            KeyPaths::FailableReadable(get) => {
907                if let Some(value) = get(&**boxed) {
908                    f(value)
909                } else {
910                    panic!("FailableReadable keypath returned None for Box")
911                }
912            }
913            _ => panic!("with_box only works with readable keypaths"),
914        }
915    }
916
917    /// Execute a closure with a mutable reference to the value inside a Box
918    /// This avoids cloning by working with references directly
919    #[inline]
920    fn with_box_mut<F, R>(self, boxed: &mut Box<Root>, f: F) -> R
921    where
922        F: FnOnce(&mut Value) -> R,
923    {
924        match self {
925            KeyPaths::Writable(get) => f(get(&mut **boxed)),
926            KeyPaths::FailableWritable(get) => {
927                if let Some(value) = get(&mut **boxed) {
928                    f(value)
929                } else {
930                    panic!("FailableWritable keypath returned None for Box")
931                }
932            }
933            _ => panic!("with_box_mut only works with writable keypaths"),
934        }
935    }
936
937    /// Execute a closure with a reference to the value inside an Rc
938    /// This avoids cloning by working with references directly
939    #[inline]
940    fn with_rc<F, R>(self, rc: &Rc<Root>, f: F) -> R
941    where
942        F: FnOnce(&Value) -> R,
943    {
944        match self {
945            KeyPaths::Readable(get) => f(get(&**rc)),
946            KeyPaths::FailableReadable(get) => {
947                if let Some(value) = get(&**rc) {
948                    f(value)
949                } else {
950                    panic!("FailableReadable keypath returned None for Rc")
951                }
952            }
953            _ => panic!("with_rc only works with readable keypaths"),
954        }
955    }
956
957    /// Execute a closure with a reference to the value inside a Result
958    /// This avoids cloning by working with references directly
959    #[inline]
960    fn with_result<F, R, E>(self, result: &Result<Root, E>, f: F) -> Option<R>
961    where
962        F: FnOnce(&Value) -> R,
963    {
964        match self {
965            KeyPaths::Readable(get) => {
966                result.as_ref().ok().map(|root| f(get(root)))
967            }
968            KeyPaths::FailableReadable(get) => {
969                result.as_ref().ok().and_then(|root| get(root).map(|v| f(v)))
970            }
971            _ => panic!("with_result only works with readable keypaths"),
972        }
973    }
974
975    /// Execute a closure with a mutable reference to the value inside a Result
976    /// This avoids cloning by working with references directly
977    #[inline]
978    fn with_result_mut<F, R, E>(self, result: &mut Result<Root, E>, f: F) -> Option<R>
979    where
980        F: FnOnce(&mut Value) -> R,
981    {
982        match self {
983            KeyPaths::Writable(get) => {
984                result.as_mut().ok().map(|root| f(get(root)))
985            }
986            KeyPaths::FailableWritable(get) => {
987                result.as_mut().ok().and_then(|root| get(root).map(|v| f(v)))
988            }
989            _ => panic!("with_result_mut only works with writable keypaths"),
990        }
991    }
992
993    /// Execute a closure with a reference to the value inside an Option
994    /// This avoids cloning by working with references directly
995    #[inline]
996    fn with_option<F, R>(self, option: &Option<Root>, f: F) -> Option<R>
997    where
998        F: FnOnce(&Value) -> R,
999    {
1000        match self {
1001            KeyPaths::Readable(get) => {
1002                option.as_ref().map(|root| f(get(root)))
1003            }
1004            KeyPaths::FailableReadable(get) => {
1005                option.as_ref().and_then(|root| get(root).map(|v| f(v)))
1006            }
1007            _ => panic!("with_option only works with readable keypaths"),
1008        }
1009    }
1010
1011    /// Execute a closure with a mutable reference to the value inside an Option
1012    /// This avoids cloning by working with references directly
1013    #[inline]
1014    fn with_option_mut<F, R>(self, option: &mut Option<Root>, f: F) -> Option<R>
1015    where
1016        F: FnOnce(&mut Value) -> R,
1017    {
1018        match self {
1019            KeyPaths::Writable(get) => {
1020                option.as_mut().map(|root| f(get(root)))
1021            }
1022            KeyPaths::FailableWritable(get) => {
1023                option.as_mut().and_then(|root| get(root).map(|v| f(v)))
1024            }
1025            _ => panic!("with_option_mut only works with writable keypaths"),
1026        }
1027    }
1028
1029    /// Execute a closure with a reference to the value inside a RefCell
1030    /// This avoids cloning by working with references directly
1031    #[inline]
1032    fn with_refcell<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
1033    where
1034        F: FnOnce(&Value) -> R,
1035    {
1036        match self {
1037            KeyPaths::Readable(get) => {
1038                refcell.try_borrow().ok().map(|borrow| f(get(&*borrow)))
1039            }
1040            KeyPaths::FailableReadable(get) => {
1041                refcell.try_borrow().ok().and_then(|borrow| get(&*borrow).map(|v| f(v)))
1042            }
1043            _ => panic!("with_refcell only works with readable keypaths"),
1044        }
1045    }
1046
1047    /// Execute a closure with a mutable reference to the value inside a RefCell
1048    /// This avoids cloning by working with references directly
1049    #[inline]
1050    fn with_refcell_mut<F, R>(self, refcell: &RefCell<Root>, f: F) -> Option<R>
1051    where
1052        F: FnOnce(&mut Value) -> R,
1053    {
1054        match self {
1055            KeyPaths::Writable(get) => {
1056                refcell.try_borrow_mut().ok().map(|mut borrow| f(get(&mut *borrow)))
1057            }
1058            KeyPaths::FailableWritable(get) => {
1059                refcell.try_borrow_mut().ok().and_then(|mut borrow| get(&mut *borrow).map(|v| f(v)))
1060            }
1061            _ => panic!("with_refcell_mut only works with writable keypaths"),
1062        }
1063    }
1064
1065    /// Execute a closure with a reference to the value inside a Tagged
1066    /// This avoids cloning by working with references directly
1067    #[cfg(feature = "tagged_core")]
1068    #[inline]
1069    fn with_tagged<F, R, Tag>(self, tagged: &Tagged<Root, Tag>, f: F) -> R
1070    where
1071        F: FnOnce(&Value) -> R,
1072    {
1073        match self {
1074            KeyPaths::Readable(get) => f(get(&**tagged)),
1075            KeyPaths::FailableReadable(get) => {
1076                get(&**tagged).map_or_else(|| panic!("Tagged value is None"), f)
1077            }
1078            KeyPaths::ReadableEnum { extract, .. } => {
1079                extract(&**tagged).map_or_else(|| panic!("Tagged value is None"), f)
1080            }
1081            _ => panic!("with_tagged only works with readable keypaths"),
1082        }
1083    }
1084
1085    /// Execute a closure with a reference to the value inside a Mutex
1086    /// This avoids cloning by working with references while the guard is alive
1087    #[inline]
1088    fn with_mutex<F, R>(self, mutex: &Mutex<Root>, f: F) -> Option<R>
1089    where
1090        F: FnOnce(&Value) -> R,
1091    {
1092        match self {
1093            KeyPaths::Readable(get) => {
1094                mutex.try_lock().ok().map(|guard| f(get(&*guard)))
1095            }
1096            KeyPaths::FailableReadable(get) => {
1097                mutex.try_lock().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
1098            }
1099            _ => panic!("with_mutex only works with readable keypaths"),
1100        }
1101    }
1102
1103    /// Execute a closure with a mutable reference to the value inside a Mutex
1104    /// This avoids cloning by working with references while the guard is alive
1105    #[inline]
1106    fn with_mutex_mut<F, R>(self, mutex: &mut Mutex<Root>, f: F) -> Option<R>
1107    where
1108        F: FnOnce(&mut Value) -> R,
1109    {
1110        match self {
1111            KeyPaths::Writable(get) => {
1112                mutex.try_lock().ok().map(|mut guard| f(get(&mut *guard)))
1113            }
1114            KeyPaths::FailableWritable(get) => {
1115                mutex.try_lock().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
1116            }
1117            _ => panic!("with_mutex_mut only works with writable keypaths"),
1118        }
1119    }
1120
1121    /// Execute a closure with a reference to the value inside an RwLock
1122    /// This avoids cloning by working with references while the guard is alive
1123    #[inline]
1124    fn with_rwlock<F, R>(self, rwlock: &RwLock<Root>, f: F) -> Option<R>
1125    where
1126        F: FnOnce(&Value) -> R,
1127    {
1128        match self {
1129            KeyPaths::Readable(get) => {
1130                rwlock.try_read().ok().map(|guard| f(get(&*guard)))
1131            }
1132            KeyPaths::FailableReadable(get) => {
1133                rwlock.try_read().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
1134            }
1135            _ => panic!("with_rwlock only works with readable keypaths"),
1136        }
1137    }
1138
1139    /// Execute a closure with a mutable reference to the value inside an RwLock
1140    /// This avoids cloning by working with references while the guard is alive
1141    #[inline]
1142    fn with_rwlock_mut<F, R>(self, rwlock: &mut RwLock<Root>, f: F) -> Option<R>
1143    where
1144        F: FnOnce(&mut Value) -> R,
1145    {
1146        match self {
1147            KeyPaths::Writable(get) => {
1148                rwlock.try_write().ok().map(|mut guard| f(get(&mut *guard)))
1149            }
1150            KeyPaths::FailableWritable(get) => {
1151                rwlock.try_write().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
1152            }
1153            _ => panic!("with_rwlock_mut only works with writable keypaths"),
1154        }
1155    }
1156
1157    /// Execute a closure with a reference to the value inside an Arc<RwLock<Root>>
1158    /// This avoids cloning by working with references while the guard is alive
1159    fn with_arc_rwlock<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
1160    where
1161        F: FnOnce(&Value) -> R,
1162    {
1163        match self {
1164            KeyPaths::Readable(get) => {
1165                arc_rwlock.try_read().ok().map(|guard| f(get(&*guard)))
1166            }
1167            KeyPaths::FailableReadable(get) => {
1168                arc_rwlock.try_read().ok().and_then(|guard| get(&*guard).map(|v| f(v)))
1169            }
1170            _ => panic!("with_arc_rwlock only works with readable keypaths"),
1171        }
1172    }
1173
1174    /// Execute a closure with a mutable reference to the value inside an Arc<RwLock<Root>>
1175    /// This avoids cloning by working with references while the guard is alive
1176    fn with_arc_rwlock_mut<F, R>(self, arc_rwlock: &Arc<RwLock<Root>>, f: F) -> Option<R>
1177    where
1178        F: FnOnce(&mut Value) -> R,
1179    {
1180        match self {
1181            KeyPaths::Writable(get) => {
1182                arc_rwlock.try_write().ok().map(|mut guard| f(get(&mut *guard)))
1183            }
1184            KeyPaths::FailableWritable(get) => {
1185                arc_rwlock.try_write().ok().and_then(|mut guard| get(&mut *guard).map(|v| f(v)))
1186            }
1187            _ => panic!("with_arc_rwlock_mut only works with writable keypaths"),
1188        }
1189    }
1190}
1191
1192impl<Root, Mid> KeyPaths<Root, Mid>
1193where
1194    Root: 'static,
1195    Mid: 'static,
1196{
1197    /// Alias for `compose` for ergonomic chaining.
1198    #[inline]
1199    pub fn then<Value>(self, mid: KeyPaths<Mid, Value>) -> KeyPaths<Root, Value>
1200    where
1201        Value: 'static,
1202    {
1203        self.compose(mid)
1204    }
1205
1206    pub fn compose<Value>(self, mid: KeyPaths<Mid, Value>) -> KeyPaths<Root, Value>
1207    where
1208        Value: 'static,
1209    {
1210        use KeyPaths::*;
1211
1212        match (self, mid) {
1213            (Readable(f1), Readable(f2)) => Readable(Arc::new(move |r| f2(f1(r)))),
1214
1215            (Writable(f1), Writable(f2)) => Writable(Arc::new(move |r| f2(f1(r)))),
1216
1217            (FailableReadable(f1), Readable(f2)) => {
1218                FailableReadable(Arc::new(move |r| f1(r).map(|m| f2(m))))
1219            }
1220
1221            (Readable(f1), FailableReadable(f2)) => FailableReadable(Arc::new(move |r| f2(f1(r)))),
1222
1223            (FailableReadable(f1), FailableReadable(f2)) => {
1224                FailableReadable(Arc::new(move |r| f1(r).and_then(|m| f2(m))))
1225            }
1226
1227            (FailableWritable(f1), Writable(f2)) => {
1228                FailableWritable(Arc::new(move |r| f1(r).map(|m| f2(m))))
1229            }
1230
1231            (Writable(f1), FailableWritable(f2)) => FailableWritable(Arc::new(move |r| f2(f1(r)))),
1232
1233            (FailableWritable(f1), FailableWritable(f2)) => {
1234                FailableWritable(Arc::new(move |r| f1(r).and_then(|m| f2(m))))
1235            }
1236            (FailableReadable(f1), ReadableEnum { extract, .. }) => {
1237                FailableReadable(Arc::new(move |r| f1(r).and_then(|m| extract(m))))
1238            }
1239            // (ReadableEnum { extract, .. }, FailableReadable(f2)) => {
1240            //     FailableReadable(Arc::new(move |r| extract(r).map(|m| f2(m).unwrap())))
1241            // }
1242            (ReadableEnum { extract, .. }, Readable(f2)) => {
1243                FailableReadable(Arc::new(move |r| extract(r).map(|m| f2(m))))
1244            }
1245
1246            (ReadableEnum { extract, .. }, FailableReadable(f2)) => {
1247                FailableReadable(Arc::new(move |r| extract(r).and_then(|m| f2(m))))
1248            }
1249
1250            (WritableEnum { extract, .. }, Readable(f2)) => {
1251                FailableReadable(Arc::new(move |r| extract(r).map(|m| f2(m))))
1252            }
1253
1254            (WritableEnum { extract, .. }, FailableReadable(f2)) => {
1255                FailableReadable(Arc::new(move |r| extract(r).and_then(|m| f2(m))))
1256            }
1257
1258            (WritableEnum { extract_mut, .. }, Writable(f2)) => {
1259                FailableWritable(Arc::new(move |r| extract_mut(r).map(|m| f2(m))))
1260            }
1261
1262            (
1263                FailableWritable(f_root_mid),
1264                WritableEnum {
1265                    extract_mut: exm_mid_val,
1266                    ..
1267                },
1268            ) => {
1269                FailableWritable(Arc::new(move |r: &mut Root| {
1270                    // First, apply the function that operates on Root.
1271                    // This will give us `Option<&mut Mid>`.
1272                    let intermediate_mid_ref = f_root_mid(r);
1273
1274                    // Then, apply the function that operates on Mid.
1275                    // This will give us `Option<&mut Value>`.
1276                    intermediate_mid_ref.and_then(|intermediate_mid| exm_mid_val(intermediate_mid))
1277                }))
1278            }
1279
1280            (WritableEnum { extract_mut, .. }, FailableWritable(f2)) => {
1281                FailableWritable(Arc::new(move |r| extract_mut(r).and_then(|m| f2(m))))
1282            }
1283
1284            // New: Writable then WritableEnum => FailableWritable
1285            (Writable(f1), WritableEnum { extract_mut, .. }) => {
1286                FailableWritable(Arc::new(move |r: &mut Root| {
1287                    let mid: &mut Mid = f1(r);
1288                    extract_mut(mid)
1289                }))
1290            }
1291
1292            (
1293                ReadableEnum {
1294                    extract: ex1,
1295                    embed: em1,
1296                },
1297                ReadableEnum {
1298                    extract: ex2,
1299                    embed: em2,
1300                },
1301            ) => ReadableEnum {
1302                extract: Arc::new(move |r| ex1(r).and_then(|m| ex2(m))),
1303                embed: Arc::new(move |v| em1(em2(v))),
1304            },
1305
1306            (
1307                WritableEnum {
1308                    extract: ex1,
1309                    extract_mut: _,
1310                    embed: em1,
1311                },
1312                ReadableEnum {
1313                    extract: ex2,
1314                    embed: em2,
1315                },
1316            ) => ReadableEnum {
1317                extract: Arc::new(move |r| ex1(r).and_then(|m| ex2(m))),
1318                embed: Arc::new(move |v| em1(em2(v))),
1319            },
1320
1321            (
1322                WritableEnum {
1323                    extract: ex1,
1324                    extract_mut: exm1,
1325                    embed: em1,
1326                },
1327                WritableEnum {
1328                    extract: ex2,
1329                    extract_mut: exm2,
1330                    embed: em2,
1331                },
1332            ) => WritableEnum {
1333                extract: Arc::new(move |r| ex1(r).and_then(|m| ex2(m))),
1334                extract_mut: Arc::new(move |r| exm1(r).and_then(|m| exm2(m))),
1335                embed: Arc::new(move |v| em1(em2(v))),
1336            },
1337
1338
1339            // New owned keypath compositions
1340            (Owned(f1), Owned(f2)) => {
1341                Owned(Arc::new(move |r| f2(f1(r))))
1342            }
1343            (FailableOwned(f1), Owned(f2)) => {
1344                FailableOwned(Arc::new(move |r| f1(r).map(|m| f2(m))))
1345            }
1346            (Owned(f1), FailableOwned(f2)) => {
1347                FailableOwned(Arc::new(move |r| f2(f1(r))))
1348            }
1349            (FailableOwned(f1), FailableOwned(f2)) => {
1350                FailableOwned(Arc::new(move |r| f1(r).and_then(|m| f2(m))))
1351            }
1352
1353            // Cross-composition between owned and regular keypaths
1354            // Note: These compositions require Clone bounds which may not always be available
1355            // For now, we'll skip these complex compositions
1356
1357            (a, b) => panic!(
1358                "Unsupported composition: {:?} then {:?}",
1359                kind_name(&a),
1360                kind_name(&b)
1361            ),
1362        }
1363    }
1364
1365    /// Get the kind name of this keypath
1366    #[inline]
1367    pub fn kind_name(&self) -> &'static str {
1368        kind_name(self)
1369    }
1370}
1371
1372fn kind_name<Root, Value>(k: &KeyPaths<Root, Value>) -> &'static str {
1373    use KeyPaths::*;
1374    match k {
1375        Readable(_) => "Readable",
1376        Writable(_) => "Writable",
1377        FailableReadable(_) => "FailableReadable",
1378        FailableWritable(_) => "FailableWritable",
1379        ReadableEnum { .. } => "ReadableEnum",
1380        WritableEnum { .. } => "WritableEnum",
1381        // New owned keypath types
1382        Owned(_) => "Owned",
1383        FailableOwned(_) => "FailableOwned",
1384    }
1385}
1386
1387// ===== Helper functions for creating reusable getter functions =====
1388// Note: These helper functions have lifetime constraints that make them
1389// difficult to implement in Rust's current type system. The keypath
1390// instances themselves can be used directly for access.
1391
1392// ===== Global compose function =====
1393
1394/// Global compose function that combines two compatible key paths
1395pub fn compose<Root, Mid, Value>(
1396    kp1: KeyPaths<Root, Mid>,
1397    kp2: KeyPaths<Mid, Value>,
1398) -> KeyPaths<Root, Value>
1399where
1400    Root: 'static,
1401    Mid: 'static,
1402    Value: 'static,
1403{
1404    kp1.compose(kp2)
1405}
1406
1407// ===== Helper macros for enum case keypaths =====
1408
1409#[macro_export]
1410macro_rules! readable_enum_macro {
1411    // Unit variant: Enum::Variant
1412    ($enum:path, $variant:ident) => {{
1413        $crate::KeyPaths::readable_enum(
1414            |_| <$enum>::$variant,
1415            |e: &$enum| match e {
1416                <$enum>::$variant => Some(&()),
1417                _ => None,
1418            },
1419        )
1420    }};
1421    // Single-field tuple variant: Enum::Variant(Inner)
1422    ($enum:path, $variant:ident($inner:ty)) => {{
1423        $crate::KeyPaths::readable_enum(
1424            |v: $inner| <$enum>::$variant(v),
1425            |e: &$enum| match e {
1426                <$enum>::$variant(v) => Some(v),
1427                _ => None,
1428            },
1429        )
1430    }};
1431}
1432
1433#[macro_export]
1434macro_rules! writable_enum_macro {
1435    // Unit variant: Enum::Variant (creates prism to and from ())
1436    ($enum:path, $variant:ident) => {{
1437        $crate::KeyPaths::writable_enum(
1438            |_| <$enum>::$variant,
1439            |e: &$enum| match e {
1440                <$enum>::$variant => Some(&()),
1441                _ => None,
1442            },
1443            |e: &mut $enum| match e {
1444                <$enum>::$variant => Some(&mut ()),
1445                _ => None,
1446            },
1447        )
1448    }};
1449    // Single-field tuple variant: Enum::Variant(Inner)
1450    ($enum:path, $variant:ident($inner:ty)) => {{
1451        $crate::KeyPaths::writable_enum(
1452            |v: $inner| <$enum>::$variant(v),
1453            |e: &$enum| match e {
1454                <$enum>::$variant(v) => Some(v),
1455                _ => None,
1456            },
1457            |e: &mut $enum| match e {
1458                <$enum>::$variant(v) => Some(v),
1459                _ => None,
1460            },
1461        )
1462    }};
1463}