rust_keypaths/
lib.rs

1use std::sync::{Arc, Mutex, RwLock};
2use std::marker::PhantomData;
3use std::any::{Any, TypeId};
4use std::rc::Rc;
5
6// Base KeyPath
7#[derive(Clone)]
8pub struct KeyPath<Root, Value, F>
9where
10    F: for<'r> Fn(&'r Root) -> &'r Value,
11{
12    getter: F,
13    _phantom: PhantomData<(Root, Value)>,
14}
15
16impl<Root, Value, F> KeyPath<Root, Value, F>
17where
18    F: for<'r> Fn(&'r Root) -> &'r Value,
19{
20    pub fn new(getter: F) -> Self {
21        Self {
22            getter,
23            _phantom: PhantomData,
24        }
25    }
26    
27    pub fn get<'r>(&self, root: &'r Root) -> &'r Value {
28        (self.getter)(root)
29}
30
31    // Instance methods for unwrapping containers (automatically infers Target from Value::Target)
32    // Box<T> -> T
33    pub fn for_box<Target>(self) -> KeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> &'r Target + 'static>
34    where
35        Value: std::ops::Deref<Target = Target>,
36        F: 'static,
37        Value: 'static,
38    {
39        let getter = self.getter;
40        
41        KeyPath {
42            getter: move |root: &Root| {
43                getter(root).deref()
44            },
45            _phantom: PhantomData,
46        }
47    }
48    
49    // Arc<T> -> T
50    pub fn for_arc<Target>(self) -> KeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> &'r Target + 'static>
51    where
52        Value: std::ops::Deref<Target = Target>,
53        F: 'static,
54        Value: 'static,
55    {
56        let getter = self.getter;
57        
58        KeyPath {
59            getter: move |root: &Root| {
60                getter(root).deref()
61            },
62            _phantom: PhantomData,
63        }
64    }
65    
66    // Rc<T> -> T
67    pub fn for_rc<Target>(self) -> KeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> &'r Target + 'static>
68    where
69        Value: std::ops::Deref<Target = Target>,
70        F: 'static,
71        Value: 'static,
72    {
73        let getter = self.getter;
74        
75        KeyPath {
76            getter: move |root: &Root| {
77                getter(root).deref()
78            },
79            _phantom: PhantomData,
80        }
81    }
82    
83    /// Convert a KeyPath to OptionalKeyPath for chaining
84    /// This allows non-optional keypaths to be chained with then()
85    pub fn to_optional(self) -> OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>
86    where
87        F: 'static,
88    {
89        let getter = self.getter;
90        OptionalKeyPath::new(move |root: &Root| Some(getter(root)))
91    }
92    
93    /// Execute a closure with a reference to the value inside an Option
94    pub fn with_option<Callback, R>(&self, option: &Option<Root>, f: Callback) -> Option<R>
95    where
96        F: Clone,
97        Callback: FnOnce(&Value) -> R,
98    {
99        option.as_ref().map(|root| {
100            let value = self.get(root);
101            f(value)
102        })
103    }
104    
105    /// Execute a closure with a reference to the value inside a Mutex
106    pub fn with_mutex<Callback, R>(&self, mutex: &Mutex<Root>, f: Callback) -> Option<R>
107    where
108        F: Clone,
109        Callback: FnOnce(&Value) -> R,
110    {
111        mutex.lock().ok().map(|guard| {
112            let value = self.get(&*guard);
113            f(value)
114        })
115    }
116    
117    /// Execute a closure with a reference to the value inside an RwLock
118    pub fn with_rwlock<Callback, R>(&self, rwlock: &RwLock<Root>, f: Callback) -> Option<R>
119    where
120        F: Clone,
121        Callback: FnOnce(&Value) -> R,
122    {
123        rwlock.read().ok().map(|guard| {
124            let value = self.get(&*guard);
125            f(value)
126        })
127    }
128    
129    /// Execute a closure with a reference to the value inside an Arc<RwLock<Root>>
130    pub fn with_arc_rwlock<Callback, R>(&self, arc_rwlock: &Arc<RwLock<Root>>, f: Callback) -> Option<R>
131    where
132        F: Clone,
133        Callback: FnOnce(&Value) -> R,
134    {
135        arc_rwlock.read().ok().map(|guard| {
136            let value = self.get(&*guard);
137            f(value)
138        })
139    }
140    
141    /// Execute a closure with a reference to the value inside an Arc<Mutex<Root>>
142    pub fn with_arc_mutex<Callback, R>(&self, arc_mutex: &Arc<Mutex<Root>>, f: Callback) -> Option<R>
143    where
144        F: Clone,
145        Callback: FnOnce(&Value) -> R,
146    {
147        arc_mutex.lock().ok().map(|guard| {
148            let value = self.get(&*guard);
149            f(value)
150        })
151    }
152    
153}
154
155// Extension methods for KeyPath to support Arc<RwLock> and Arc<Mutex> directly
156impl<Root, Value, F> KeyPath<Root, Value, F>
157where
158    F: for<'r> Fn(&'r Root) -> &'r Value + Clone,
159{
160    /// Execute a closure with a reference to the value inside an Arc<RwLock<Root>>
161    /// This is a convenience method that works directly with Arc<RwLock<T>>
162    pub fn with_arc_rwlock_direct<Callback, R>(&self, arc_rwlock: &Arc<RwLock<Root>>, f: Callback) -> Option<R>
163    where
164        Callback: FnOnce(&Value) -> R,
165    {
166        arc_rwlock.read().ok().map(|guard| {
167            let value = self.get(&*guard);
168            f(value)
169        })
170    }
171    
172    /// Execute a closure with a reference to the value inside an Arc<Mutex<Root>>
173    /// This is a convenience method that works directly with Arc<Mutex<T>>
174    pub fn with_arc_mutex_direct<Callback, R>(&self, arc_mutex: &Arc<Mutex<Root>>, f: Callback) -> Option<R>
175    where
176        Callback: FnOnce(&Value) -> R,
177    {
178        arc_mutex.lock().ok().map(|guard| {
179            let value = self.get(&*guard);
180            f(value)
181        })
182    }
183}
184
185// Utility function for slice access (kept as standalone function)
186pub fn for_slice<T>() -> impl for<'r> Fn(&'r [T], usize) -> Option<&'r T> {
187    |slice: &[T], index: usize| slice.get(index)
188}
189
190// Container access utilities
191pub mod containers {
192    use super::{OptionalKeyPath, WritableOptionalKeyPath, KeyPath, WritableKeyPath};
193    use std::collections::{HashMap, BTreeMap, HashSet, BTreeSet, VecDeque, LinkedList, BinaryHeap};
194    use std::sync::{Mutex, RwLock, Weak as StdWeak, Arc};
195    use std::rc::{Weak as RcWeak, Rc};
196    use std::ops::{Deref, DerefMut};
197
198    #[cfg(feature = "parking_lot")]
199    use parking_lot::{Mutex as ParkingMutex, RwLock as ParkingRwLock};
200
201    #[cfg(feature = "tagged")]
202    use tagged_core::Tagged;
203
204    /// Create a keypath for indexed access in Vec<T>
205    pub fn for_vec_index<T>(index: usize) -> OptionalKeyPath<Vec<T>, T, impl for<'r> Fn(&'r Vec<T>) -> Option<&'r T>> {
206        OptionalKeyPath::new(move |vec: &Vec<T>| vec.get(index))
207    }
208
209    /// Create a keypath for indexed access in VecDeque<T>
210    pub fn for_vecdeque_index<T>(index: usize) -> OptionalKeyPath<VecDeque<T>, T, impl for<'r> Fn(&'r VecDeque<T>) -> Option<&'r T>> {
211        OptionalKeyPath::new(move |deque: &VecDeque<T>| deque.get(index))
212    }
213
214    /// Create a keypath for indexed access in LinkedList<T>
215    pub fn for_linkedlist_index<T>(index: usize) -> OptionalKeyPath<LinkedList<T>, T, impl for<'r> Fn(&'r LinkedList<T>) -> Option<&'r T>> {
216        OptionalKeyPath::new(move |list: &LinkedList<T>| {
217            list.iter().nth(index)
218        })
219    }
220
221    /// Create a keypath for key-based access in HashMap<K, V>
222    pub fn for_hashmap_key<K, V>(key: K) -> OptionalKeyPath<HashMap<K, V>, V, impl for<'r> Fn(&'r HashMap<K, V>) -> Option<&'r V>>
223    where
224        K: std::hash::Hash + Eq + Clone + 'static,
225        V: 'static,
226    {
227        OptionalKeyPath::new(move |map: &HashMap<K, V>| map.get(&key))
228    }
229
230    /// Create a keypath for key-based access in BTreeMap<K, V>
231    pub fn for_btreemap_key<K, V>(key: K) -> OptionalKeyPath<BTreeMap<K, V>, V, impl for<'r> Fn(&'r BTreeMap<K, V>) -> Option<&'r V>>
232    where
233        K: Ord + Clone + 'static,
234        V: 'static,
235    {
236        OptionalKeyPath::new(move |map: &BTreeMap<K, V>| map.get(&key))
237    }
238
239    /// Create a keypath for getting a value from HashSet<T> (returns Option<&T>)
240    pub fn for_hashset_get<T>(value: T) -> OptionalKeyPath<HashSet<T>, T, impl for<'r> Fn(&'r HashSet<T>) -> Option<&'r T>>
241    where
242        T: std::hash::Hash + Eq + Clone + 'static,
243    {
244        OptionalKeyPath::new(move |set: &HashSet<T>| set.get(&value))
245    }
246
247    /// Create a keypath for checking membership in BTreeSet<T>
248    pub fn for_btreeset_get<T>(value: T) -> OptionalKeyPath<BTreeSet<T>, T, impl for<'r> Fn(&'r BTreeSet<T>) -> Option<&'r T>>
249    where
250        T: Ord + Clone + 'static,
251    {
252        OptionalKeyPath::new(move |set: &BTreeSet<T>| set.get(&value))
253    }
254
255    /// Create a keypath for peeking at the top of BinaryHeap<T>
256    pub fn for_binaryheap_peek<T>() -> OptionalKeyPath<BinaryHeap<T>, T, impl for<'r> Fn(&'r BinaryHeap<T>) -> Option<&'r T>>
257    where
258        T: Ord + 'static,
259    {
260        OptionalKeyPath::new(|heap: &BinaryHeap<T>| heap.peek())
261    }
262
263    // ========== WRITABLE VERSIONS ==========
264
265    /// Create a writable keypath for indexed access in Vec<T>
266    pub fn for_vec_index_mut<T>(index: usize) -> WritableOptionalKeyPath<Vec<T>, T, impl for<'r> Fn(&'r mut Vec<T>) -> Option<&'r mut T>> {
267        WritableOptionalKeyPath::new(move |vec: &mut Vec<T>| vec.get_mut(index))
268    }
269
270    /// Create a writable keypath for indexed access in VecDeque<T>
271    pub fn for_vecdeque_index_mut<T>(index: usize) -> WritableOptionalKeyPath<VecDeque<T>, T, impl for<'r> Fn(&'r mut VecDeque<T>) -> Option<&'r mut T>> {
272        WritableOptionalKeyPath::new(move |deque: &mut VecDeque<T>| deque.get_mut(index))
273    }
274
275    /// Create a writable keypath for indexed access in LinkedList<T>
276    pub fn for_linkedlist_index_mut<T>(index: usize) -> WritableOptionalKeyPath<LinkedList<T>, T, impl for<'r> Fn(&'r mut LinkedList<T>) -> Option<&'r mut T>> {
277        WritableOptionalKeyPath::new(move |list: &mut LinkedList<T>| {
278            // LinkedList doesn't have get_mut, so we need to iterate
279            let mut iter = list.iter_mut();
280            iter.nth(index)
281        })
282    }
283
284    /// Create a writable keypath for key-based access in HashMap<K, V>
285    pub fn for_hashmap_key_mut<K, V>(key: K) -> WritableOptionalKeyPath<HashMap<K, V>, V, impl for<'r> Fn(&'r mut HashMap<K, V>) -> Option<&'r mut V>>
286    where
287        K: std::hash::Hash + Eq + Clone + 'static,
288        V: 'static,
289    {
290        WritableOptionalKeyPath::new(move |map: &mut HashMap<K, V>| map.get_mut(&key))
291    }
292
293    /// Create a writable keypath for key-based access in BTreeMap<K, V>
294    pub fn for_btreemap_key_mut<K, V>(key: K) -> WritableOptionalKeyPath<BTreeMap<K, V>, V, impl for<'r> Fn(&'r mut BTreeMap<K, V>) -> Option<&'r mut V>>
295    where
296        K: Ord + Clone + 'static,
297        V: 'static,
298    {
299        WritableOptionalKeyPath::new(move |map: &mut BTreeMap<K, V>| map.get_mut(&key))
300    }
301
302    /// Create a writable keypath for getting a mutable value from HashSet<T>
303    /// Note: HashSet doesn't support mutable access to elements, but we provide it for consistency
304    pub fn for_hashset_get_mut<T>(value: T) -> WritableOptionalKeyPath<HashSet<T>, T, impl for<'r> Fn(&'r mut HashSet<T>) -> Option<&'r mut T>>
305    where
306        T: std::hash::Hash + Eq + Clone + 'static,
307    {
308        WritableOptionalKeyPath::new(move |set: &mut HashSet<T>| {
309            // HashSet doesn't have get_mut, so we need to check and return None
310            // This is a limitation of HashSet's design
311            if set.contains(&value) {
312                // We can't return a mutable reference to the value in the set
313                // This is a fundamental limitation of HashSet
314                None
315            } else {
316                None
317            }
318        })
319    }
320
321    /// Create a writable keypath for getting a mutable value from BTreeSet<T>
322    /// Note: BTreeSet doesn't support mutable access to elements, but we provide it for consistency
323    pub fn for_btreeset_get_mut<T>(value: T) -> WritableOptionalKeyPath<BTreeSet<T>, T, impl for<'r> Fn(&'r mut BTreeSet<T>) -> Option<&'r mut T>>
324    where
325        T: Ord + Clone + 'static,
326    {
327        WritableOptionalKeyPath::new(move |set: &mut BTreeSet<T>| {
328            // BTreeSet doesn't have get_mut, so we need to check and return None
329            // This is a limitation of BTreeSet's design
330            if set.contains(&value) {
331                // We can't return a mutable reference to the value in the set
332                // This is a fundamental limitation of BTreeSet
333                None
334            } else {
335                None
336            }
337        })
338    }
339
340    /// Create a writable keypath for peeking at the top of BinaryHeap<T>
341    /// Note: BinaryHeap.peek_mut() returns PeekMut which is a guard type.
342    /// Due to Rust's borrowing rules, we cannot return &mut T directly from PeekMut.
343    /// This function returns None as BinaryHeap doesn't support direct mutable access
344    /// through keypaths. Use heap.peek_mut() directly for mutable access.
345    pub fn for_binaryheap_peek_mut<T>() -> WritableOptionalKeyPath<BinaryHeap<T>, T, impl for<'r> Fn(&'r mut BinaryHeap<T>) -> Option<&'r mut T>>
346    where
347        T: Ord + 'static,
348    {
349        // BinaryHeap.peek_mut() returns PeekMut which is a guard type that owns the mutable reference.
350        // We cannot return &mut T from it due to lifetime constraints.
351        // This is a fundamental limitation - use heap.peek_mut() directly instead.
352        WritableOptionalKeyPath::new(|_heap: &mut BinaryHeap<T>| {
353            None
354        })
355    }
356
357    // ========== SYNCHRONIZATION PRIMITIVES ==========
358    // Note: Mutex and RwLock return guards that own the lock, not references.
359    // We cannot create keypaths that return references from guards due to lifetime constraints.
360    // These helper functions are provided for convenience, but direct lock()/read()/write() calls are recommended.
361
362    /// Helper function to lock a Mutex<T> and access its value
363    /// Returns None if the mutex is poisoned
364    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
365    pub fn lock_mutex<T>(mutex: &Mutex<T>) -> Option<std::sync::MutexGuard<'_, T>> {
366        mutex.lock().ok()
367    }
368
369    /// Helper function to read-lock an RwLock<T> and access its value
370    /// Returns None if the lock is poisoned
371    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
372    pub fn read_rwlock<T>(rwlock: &RwLock<T>) -> Option<std::sync::RwLockReadGuard<'_, T>> {
373        rwlock.read().ok()
374    }
375
376    /// Helper function to write-lock an RwLock<T> and access its value
377    /// Returns None if the lock is poisoned
378    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
379    pub fn write_rwlock<T>(rwlock: &RwLock<T>) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
380        rwlock.write().ok()
381    }
382
383    /// Helper function to lock an Arc<Mutex<T>> and access its value
384    /// Returns None if the mutex is poisoned
385    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
386    pub fn lock_arc_mutex<T>(arc_mutex: &Arc<Mutex<T>>) -> Option<std::sync::MutexGuard<'_, T>> {
387        arc_mutex.lock().ok()
388    }
389
390    /// Helper function to read-lock an Arc<RwLock<T>> and access its value
391    /// Returns None if the lock is poisoned
392    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
393    pub fn read_arc_rwlock<T>(arc_rwlock: &Arc<RwLock<T>>) -> Option<std::sync::RwLockReadGuard<'_, T>> {
394        arc_rwlock.read().ok()
395    }
396
397    /// Helper function to write-lock an Arc<RwLock<T>> and access its value
398    /// Returns None if the lock is poisoned
399    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
400    pub fn write_arc_rwlock<T>(arc_rwlock: &Arc<RwLock<T>>) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
401        arc_rwlock.write().ok()
402    }
403
404    /// Helper function to upgrade a Weak<T> to Arc<T>
405    /// Returns None if the Arc has been dropped
406    /// Note: This returns an owned Arc, not a reference, so it cannot be used in keypaths directly
407    pub fn upgrade_weak<T>(weak: &StdWeak<T>) -> Option<Arc<T>> {
408        weak.upgrade()
409    }
410
411    /// Helper function to upgrade an Rc::Weak<T> to Rc<T>
412    /// Returns None if the Rc has been dropped
413    /// Note: This returns an owned Rc, not a reference, so it cannot be used in keypaths directly
414    pub fn upgrade_rc_weak<T>(weak: &RcWeak<T>) -> Option<Rc<T>> {
415        weak.upgrade()
416    }
417
418    #[cfg(feature = "parking_lot")]
419    /// Helper function to lock a parking_lot::Mutex<T> and access its value
420    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
421    pub fn lock_parking_mutex<T>(mutex: &ParkingMutex<T>) -> parking_lot::MutexGuard<'_, T> {
422        mutex.lock()
423    }
424
425    #[cfg(feature = "parking_lot")]
426    /// Helper function to read-lock a parking_lot::RwLock<T> and access its value
427    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
428    pub fn read_parking_rwlock<T>(rwlock: &ParkingRwLock<T>) -> parking_lot::RwLockReadGuard<'_, T> {
429        rwlock.read()
430    }
431
432    #[cfg(feature = "parking_lot")]
433    /// Helper function to write-lock a parking_lot::RwLock<T> and access its value
434    /// Note: This returns a guard, not a reference, so it cannot be used in keypaths directly
435    pub fn write_parking_rwlock<T>(rwlock: &ParkingRwLock<T>) -> parking_lot::RwLockWriteGuard<'_, T> {
436        rwlock.write()
437    }
438
439    #[cfg(feature = "tagged")]
440    /// Create a keypath for accessing the inner value of Tagged<Tag, T>
441    /// Tagged implements Deref, so we can access the inner value directly
442    pub fn for_tagged<Tag, T>() -> KeyPath<Tagged<Tag, T>, T, impl for<'r> Fn(&'r Tagged<Tag, T>) -> &'r T>
443    where
444        Tagged<Tag, T>: std::ops::Deref<Target = T>,
445        Tag: 'static,
446        T: 'static,
447    {
448        KeyPath::new(|tagged: &Tagged<Tag, T>| tagged.deref())
449    }
450
451    #[cfg(feature = "tagged")]
452    /// Create a writable keypath for accessing the inner value of Tagged<Tag, T>
453    /// Tagged implements DerefMut, so we can access the inner value directly
454    pub fn for_tagged_mut<Tag, T>() -> WritableKeyPath<Tagged<Tag, T>, T, impl for<'r> Fn(&'r mut Tagged<Tag, T>) -> &'r mut T>
455    where
456        Tagged<Tag, T>: std::ops::DerefMut<Target = T>,
457        Tag: 'static,
458        T: 'static,
459    {
460        WritableKeyPath::new(|tagged: &mut Tagged<Tag, T>| tagged.deref_mut())
461    }
462}
463
464// OptionalKeyPath for Option<T>
465#[derive(Clone)]
466pub struct OptionalKeyPath<Root, Value, F>
467where
468    F: for<'r> Fn(&'r Root) -> Option<&'r Value>,
469{
470    getter: F,
471    _phantom: PhantomData<(Root, Value)>,
472}
473
474impl<Root, Value, F> OptionalKeyPath<Root, Value, F>
475where
476    F: for<'r> Fn(&'r Root) -> Option<&'r Value>,
477{
478    pub fn new(getter: F) -> Self {
479        Self {
480            getter,
481            _phantom: PhantomData,
482        }
483    }
484    
485    pub fn get<'r>(&self, root: &'r Root) -> Option<&'r Value> {
486        (self.getter)(root)
487    }
488    
489    // Swift-like operator for chaining OptionalKeyPath
490    pub fn then<SubValue, G>(
491        self,
492        next: OptionalKeyPath<Value, SubValue, G>,
493    ) -> OptionalKeyPath<Root, SubValue, impl for<'r> Fn(&'r Root) -> Option<&'r SubValue>>
494    where
495        G: for<'r> Fn(&'r Value) -> Option<&'r SubValue>,
496        F: 'static,
497        G: 'static,
498        Value: 'static,
499    {
500        let first = self.getter;
501        let second = next.getter;
502        
503        OptionalKeyPath::new(move |root: &Root| {
504            first(root).and_then(|value| second(value))
505        })
506    }
507    
508    // Instance methods for unwrapping containers from Option<Container<T>>
509    // Option<Box<T>> -> Option<&T> (type automatically inferred from Value::Target)
510    pub fn for_box<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
511    where
512        Value: std::ops::Deref<Target = Target>,
513        F: 'static,
514        Value: 'static,
515    {
516        let getter = self.getter;
517        
518        OptionalKeyPath {
519            getter: move |root: &Root| {
520                getter(root).map(|boxed| boxed.deref())
521            },
522            _phantom: PhantomData,
523        }
524    }
525    
526    // Option<Arc<T>> -> Option<&T> (type automatically inferred from Value::Target)
527    pub fn for_arc<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
528    where
529        Value: std::ops::Deref<Target = Target>,
530        F: 'static,
531        Value: 'static,
532    {
533        let getter = self.getter;
534        
535        OptionalKeyPath {
536            getter: move |root: &Root| {
537                getter(root).map(|arc| arc.deref())
538            },
539            _phantom: PhantomData,
540        }
541    }
542    
543    // Option<Rc<T>> -> Option<&T> (type automatically inferred from Value::Target)
544    pub fn for_rc<Target>(self) -> OptionalKeyPath<Root, Target, impl for<'r> Fn(&'r Root) -> Option<&'r Target> + 'static>
545    where
546        Value: std::ops::Deref<Target = Target>,
547        F: 'static,
548        Value: 'static,
549    {
550        let getter = self.getter;
551        
552        OptionalKeyPath {
553            getter: move |root: &Root| {
554                getter(root).map(|rc| rc.deref())
555            },
556            _phantom: PhantomData,
557        }
558    }
559    
560    // Static method for Option<T> -> Option<&T>
561    pub fn for_option<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
562        OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
563    }
564    
565    /// Execute a closure with a reference to the value inside an Option
566    pub fn with_option<Callback, R>(&self, option: &Option<Root>, f: Callback) -> Option<R>
567    where
568        F: Clone,
569        Callback: FnOnce(&Value) -> R,
570    {
571        option.as_ref().and_then(|root| {
572            self.get(root).map(|value| f(value))
573        })
574    }
575    
576    /// Execute a closure with a reference to the value inside a Mutex
577    pub fn with_mutex<Callback, R>(&self, mutex: &Mutex<Root>, f: Callback) -> Option<R>
578    where
579        F: Clone,
580        Callback: FnOnce(&Value) -> R,
581    {
582        mutex.lock().ok().and_then(|guard| {
583            self.get(&*guard).map(|value| f(value))
584        })
585    }
586    
587    /// Execute a closure with a reference to the value inside an RwLock
588    pub fn with_rwlock<Callback, R>(&self, rwlock: &RwLock<Root>, f: Callback) -> Option<R>
589    where
590        F: Clone,
591        Callback: FnOnce(&Value) -> R,
592    {
593        rwlock.read().ok().and_then(|guard| {
594            self.get(&*guard).map(|value| f(value))
595        })
596    }
597    
598    /// Execute a closure with a reference to the value inside an Arc<RwLock<Root>>
599    pub fn with_arc_rwlock<Callback, R>(&self, arc_rwlock: &Arc<RwLock<Root>>, f: Callback) -> Option<R>
600    where
601        F: Clone,
602        Callback: FnOnce(&Value) -> R,
603    {
604        arc_rwlock.read().ok().and_then(|guard| {
605            self.get(&*guard).map(|value| f(value))
606        })
607    }
608    
609    /// Execute a closure with a reference to the value inside an Arc<Mutex<Root>>
610    pub fn with_arc_mutex<Callback, R>(&self, arc_mutex: &Arc<Mutex<Root>>, f: Callback) -> Option<R>
611    where
612        F: Clone,
613        Callback: FnOnce(&Value) -> R,
614    {
615        arc_mutex.lock().ok().and_then(|guard| {
616            self.get(&*guard).map(|value| f(value))
617        })
618    }
619}
620
621
622// WritableKeyPath for mutable access
623#[derive(Clone)]
624pub struct WritableKeyPath<Root, Value, F>
625where
626    F: for<'r> Fn(&'r mut Root) -> &'r mut Value,
627{
628    getter: F,
629    _phantom: PhantomData<(Root, Value)>,
630}
631
632impl<Root, Value, F> WritableKeyPath<Root, Value, F>
633where
634    F: for<'r> Fn(&'r mut Root) -> &'r mut Value,
635{
636    pub fn new(getter: F) -> Self {
637        Self {
638            getter,
639            _phantom: PhantomData,
640        }
641    }
642    
643    pub fn get_mut<'r>(&self, root: &'r mut Root) -> &'r mut Value {
644        (self.getter)(root)
645    }
646    
647    /// Convert a WritableKeyPath to WritableOptionalKeyPath for chaining
648    /// This allows non-optional writable keypaths to be chained with then()
649    pub fn to_optional(self) -> WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>
650    where
651        F: 'static,
652    {
653        let getter = self.getter;
654        WritableOptionalKeyPath::new(move |root: &mut Root| Some(getter(root)))
655    }
656    
657    // Instance methods for unwrapping containers (automatically infers Target from Value::Target)
658    // Box<T> -> T
659    pub fn for_box<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
660    where
661        Value: std::ops::DerefMut<Target = Target>,
662        F: 'static,
663        Value: 'static,
664    {
665        let getter = self.getter;
666        
667        WritableKeyPath {
668            getter: move |root: &mut Root| {
669                getter(root).deref_mut()
670            },
671            _phantom: PhantomData,
672        }
673    }
674    
675    // Arc<T> -> T (Note: Arc doesn't support mutable access, but we provide it for consistency)
676    // This will require interior mutability patterns
677    pub fn for_arc<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
678    where
679        Value: std::ops::DerefMut<Target = Target>,
680        F: 'static,
681        Value: 'static,
682    {
683        let getter = self.getter;
684        
685        WritableKeyPath {
686            getter: move |root: &mut Root| {
687                getter(root).deref_mut()
688            },
689            _phantom: PhantomData,
690        }
691    }
692    
693    // Rc<T> -> T (Note: Rc doesn't support mutable access, but we provide it for consistency)
694    // This will require interior mutability patterns
695    pub fn for_rc<Target>(self) -> WritableKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> &'r mut Target + 'static>
696    where
697        Value: std::ops::DerefMut<Target = Target>,
698        F: 'static,
699        Value: 'static,
700    {
701        let getter = self.getter;
702        
703        WritableKeyPath {
704            getter: move |root: &mut Root| {
705                getter(root).deref_mut()
706            },
707            _phantom: PhantomData,
708        }
709    }
710}
711
712// WritableOptionalKeyPath for failable mutable access
713#[derive(Clone)]
714pub struct WritableOptionalKeyPath<Root, Value, F>
715where
716    F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value>,
717{
718    getter: F,
719    _phantom: PhantomData<(Root, Value)>,
720}
721
722impl<Root, Value, F> WritableOptionalKeyPath<Root, Value, F>
723where
724    F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value>,
725{
726    pub fn new(getter: F) -> Self {
727        Self {
728            getter,
729            _phantom: PhantomData,
730        }
731    }
732    
733    pub fn get_mut<'r>(&self, root: &'r mut Root) -> Option<&'r mut Value> {
734        (self.getter)(root)
735    }
736    
737    // Swift-like operator for chaining WritableOptionalKeyPath
738    pub fn then<SubValue, G>(
739        self,
740        next: WritableOptionalKeyPath<Value, SubValue, G>,
741    ) -> WritableOptionalKeyPath<Root, SubValue, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut SubValue>>
742    where
743        G: for<'r> Fn(&'r mut Value) -> Option<&'r mut SubValue>,
744        F: 'static,
745        G: 'static,
746        Value: 'static,
747    {
748        let first = self.getter;
749        let second = next.getter;
750        
751        WritableOptionalKeyPath::new(move |root: &mut Root| {
752            first(root).and_then(|value| second(value))
753        })
754    }
755    
756    // Instance methods for unwrapping containers from Option<Container<T>>
757    // Option<Box<T>> -> Option<&mut T> (type automatically inferred from Value::Target)
758    pub fn for_box<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
759    where
760        Value: std::ops::DerefMut<Target = Target>,
761        F: 'static,
762        Value: 'static,
763    {
764        let getter = self.getter;
765        
766        WritableOptionalKeyPath {
767            getter: move |root: &mut Root| {
768                getter(root).map(|boxed| boxed.deref_mut())
769            },
770            _phantom: PhantomData,
771        }
772    }
773    
774    // Option<Arc<T>> -> Option<&mut T> (type automatically inferred from Value::Target)
775    pub fn for_arc<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
776    where
777        Value: std::ops::DerefMut<Target = Target>,
778        F: 'static,
779        Value: 'static,
780    {
781        let getter = self.getter;
782        
783        WritableOptionalKeyPath {
784            getter: move |root: &mut Root| {
785                getter(root).map(|arc| arc.deref_mut())
786            },
787            _phantom: PhantomData,
788        }
789    }
790    
791    // Option<Rc<T>> -> Option<&mut T> (type automatically inferred from Value::Target)
792    pub fn for_rc<Target>(self) -> WritableOptionalKeyPath<Root, Target, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Target> + 'static>
793    where
794        Value: std::ops::DerefMut<Target = Target>,
795        F: 'static,
796        Value: 'static,
797    {
798        let getter = self.getter;
799        
800        WritableOptionalKeyPath {
801            getter: move |root: &mut Root| {
802                getter(root).map(|rc| rc.deref_mut())
803            },
804            _phantom: PhantomData,
805        }
806    }
807    
808    // Static method for Option<T> -> Option<&mut T>
809    pub fn for_option<T>() -> WritableOptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r mut Option<T>) -> Option<&'r mut T>> {
810        WritableOptionalKeyPath::new(|opt: &mut Option<T>| opt.as_mut())
811    }
812}
813
814// Enum-specific keypaths
815#[derive(Clone)]
816pub struct EnumKeyPaths;
817
818impl EnumKeyPaths {
819    // Extract from a specific enum variant
820    pub fn for_variant<Enum, Variant, ExtractFn>(
821        extractor: ExtractFn
822    ) -> OptionalKeyPath<Enum, Variant, impl for<'r> Fn(&'r Enum) -> Option<&'r Variant>>
823    where
824        ExtractFn: Fn(&Enum) -> Option<&Variant>,
825    {
826        OptionalKeyPath::new(extractor)
827    }
828    
829    // Match against multiple variants (returns a tagged union)
830    pub fn for_match<Enum, Output, MatchFn>(
831        matcher: MatchFn
832    ) -> KeyPath<Enum, Output, impl for<'r> Fn(&'r Enum) -> &'r Output>
833    where
834        MatchFn: Fn(&Enum) -> &Output,
835    {
836        KeyPath::new(matcher)
837    }
838    
839    // Extract from Result<T, E>
840    pub fn for_ok<T, E>() -> OptionalKeyPath<Result<T, E>, T, impl for<'r> Fn(&'r Result<T, E>) -> Option<&'r T>> {
841        OptionalKeyPath::new(|result: &Result<T, E>| result.as_ref().ok())
842    }
843    
844    pub fn for_err<T, E>() -> OptionalKeyPath<Result<T, E>, E, impl for<'r> Fn(&'r Result<T, E>) -> Option<&'r E>> {
845        OptionalKeyPath::new(|result: &Result<T, E>| result.as_ref().err())
846    }
847    
848    // Extract from Option<T>
849    pub fn for_some<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
850        OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
851    }
852    
853    // Static method for Option<T> -> Option<&T> (alias for for_some for consistency)
854    pub fn for_option<T>() -> OptionalKeyPath<Option<T>, T, impl for<'r> Fn(&'r Option<T>) -> Option<&'r T>> {
855        OptionalKeyPath::new(|opt: &Option<T>| opt.as_ref())
856    }
857    
858    // Static methods for container unwrapping (returns KeyPath)
859    // Box<T> -> T
860    pub fn for_box<T>() -> KeyPath<Box<T>, T, impl for<'r> Fn(&'r Box<T>) -> &'r T> {
861        KeyPath::new(|b: &Box<T>| b.as_ref())
862    }
863    
864    // Arc<T> -> T
865    pub fn for_arc<T>() -> KeyPath<Arc<T>, T, impl for<'r> Fn(&'r Arc<T>) -> &'r T> {
866        KeyPath::new(|arc: &Arc<T>| arc.as_ref())
867    }
868    
869    // Rc<T> -> T
870    pub fn for_rc<T>() -> KeyPath<std::rc::Rc<T>, T, impl for<'r> Fn(&'r std::rc::Rc<T>) -> &'r T> {
871        KeyPath::new(|rc: &std::rc::Rc<T>| rc.as_ref())
872    }
873
874    // Writable versions
875    // Box<T> -> T (mutable)
876    pub fn for_box_mut<T>() -> WritableKeyPath<Box<T>, T, impl for<'r> Fn(&'r mut Box<T>) -> &'r mut T> {
877        WritableKeyPath::new(|b: &mut Box<T>| b.as_mut())
878    }
879
880    // Note: Arc<T> and Rc<T> don't support direct mutable access without interior mutability
881    // (e.g., Arc<Mutex<T>> or Rc<RefCell<T>>). These methods are not provided as they
882    // would require unsafe code or interior mutability patterns.
883}
884
885// Helper to create enum variant keypaths with type inference
886pub fn variant_of<Enum, Variant, F>(extractor: F) -> OptionalKeyPath<Enum, Variant, F>
887where
888    F: for<'r> Fn(&'r Enum) -> Option<&'r Variant>,
889{
890    OptionalKeyPath::new(extractor)
891}
892
893// ========== PARTIAL KEYPATHS (Hide Value Type) ==========
894
895/// PartialKeyPath - Hides the Value type but keeps Root visible
896/// Useful for storing keypaths in collections without knowing the exact Value type
897/// 
898/// # Why PhantomData<Root>?
899/// 
900/// `PhantomData<Root>` is needed because:
901/// 1. The `Root` type parameter is not actually stored in the struct (only used in the closure)
902/// 2. Rust needs to know the generic type parameter for:
903///    - Type checking at compile time
904///    - Ensuring correct usage (e.g., `PartialKeyPath<User>` can only be used with `&User`)
905///    - Preventing mixing different Root types
906/// 3. Without `PhantomData`, Rust would complain that `Root` is unused
907/// 4. `PhantomData` is zero-sized - it adds no runtime overhead
908#[derive(Clone)]
909pub struct PartialKeyPath<Root> {
910    getter: Rc<dyn for<'r> Fn(&'r Root) -> &'r dyn Any>,
911    value_type_id: TypeId,
912    _phantom: PhantomData<Root>,
913}
914
915impl<Root> PartialKeyPath<Root> {
916    pub fn new<Value>(keypath: KeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> &'r Value + 'static>) -> Self
917    where
918        Value: Any + 'static,
919        Root: 'static,
920    {
921        let value_type_id = TypeId::of::<Value>();
922        let getter = Rc::new(keypath.getter);
923        
924        Self {
925            getter: Rc::new(move |root: &Root| {
926                let value: &Value = getter(root);
927                value as &dyn Any
928            }),
929            value_type_id,
930            _phantom: PhantomData,
931        }
932    }
933    
934    /// Create a PartialKeyPath from a concrete KeyPath
935    /// Alias for `new()` for consistency with `from()` pattern
936    pub fn from<Value>(keypath: KeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> &'r Value + 'static>) -> Self
937    where
938        Value: Any + 'static,
939        Root: 'static,
940    {
941        Self::new(keypath)
942    }
943    
944    pub fn get<'r>(&self, root: &'r Root) -> &'r dyn Any {
945        (self.getter)(root)
946    }
947    
948    /// Get the TypeId of the Value type
949    pub fn value_type_id(&self) -> TypeId {
950        self.value_type_id
951    }
952    
953    /// Try to downcast the result to a specific type
954    pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
955        if self.value_type_id == TypeId::of::<Value>() {
956            self.get(root).downcast_ref::<Value>()
957        } else {
958            None
959        }
960    }
961}
962
963/// PartialOptionalKeyPath - Hides the Value type but keeps Root visible
964/// Useful for storing optional keypaths in collections without knowing the exact Value type
965/// 
966/// # Why PhantomData<Root>?
967/// 
968/// See `PartialKeyPath` documentation for explanation of why `PhantomData` is needed.
969#[derive(Clone)]
970pub struct PartialOptionalKeyPath<Root> {
971    getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
972    value_type_id: TypeId,
973    _phantom: PhantomData<Root>,
974}
975
976impl<Root> PartialOptionalKeyPath<Root> {
977    pub fn new<Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
978    where
979        Value: Any + 'static,
980        Root: 'static,
981    {
982        let value_type_id = TypeId::of::<Value>();
983        let getter = Rc::new(keypath.getter);
984        
985        Self {
986            getter: Rc::new(move |root: &Root| {
987                getter(root).map(|value: &Value| value as &dyn Any)
988            }),
989            value_type_id,
990            _phantom: PhantomData,
991        }
992    }
993    
994    pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
995        (self.getter)(root)
996    }
997    
998    /// Get the TypeId of the Value type
999    pub fn value_type_id(&self) -> TypeId {
1000        self.value_type_id
1001    }
1002    
1003    /// Try to downcast the result to a specific type
1004    pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
1005        if self.value_type_id == TypeId::of::<Value>() {
1006            self.get(root).map(|any| any.downcast_ref::<Value>())
1007        } else {
1008            None
1009        }
1010    }
1011    
1012    /// Chain with another PartialOptionalKeyPath
1013    /// Note: This requires the Value type of the first keypath to match the Root type of the second
1014    /// For type-erased chaining, consider using AnyKeyPath instead
1015    pub fn then<MidValue>(
1016        self,
1017        next: PartialOptionalKeyPath<MidValue>,
1018    ) -> PartialOptionalKeyPath<Root>
1019    where
1020        MidValue: Any + 'static,
1021        Root: 'static,
1022    {
1023        let first = self.getter;
1024        let second = next.getter;
1025        let value_type_id = next.value_type_id;
1026        
1027        PartialOptionalKeyPath {
1028            getter: Rc::new(move |root: &Root| {
1029                first(root).and_then(|any| {
1030                    if let Some(mid_value) = any.downcast_ref::<MidValue>() {
1031                        second(mid_value)
1032                    } else {
1033                        None
1034                    }
1035                })
1036            }),
1037            value_type_id,
1038            _phantom: PhantomData,
1039        }
1040    }
1041}
1042
1043/// PartialWritableKeyPath - Hides the Value type but keeps Root visible (writable)
1044/// 
1045/// # Why PhantomData<Root>?
1046/// 
1047/// See `PartialKeyPath` documentation for explanation of why `PhantomData` is needed.
1048#[derive(Clone)]
1049pub struct PartialWritableKeyPath<Root> {
1050    getter: Rc<dyn for<'r> Fn(&'r mut Root) -> &'r mut dyn Any>,
1051    value_type_id: TypeId,
1052    _phantom: PhantomData<Root>,
1053}
1054
1055impl<Root> PartialWritableKeyPath<Root> {
1056    pub fn new<Value>(keypath: WritableKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static>) -> Self
1057    where
1058        Value: Any + 'static,
1059        Root: 'static,
1060    {
1061        let value_type_id = TypeId::of::<Value>();
1062        let getter = Rc::new(keypath.getter);
1063        
1064        Self {
1065            getter: Rc::new(move |root: &mut Root| {
1066                let value: &mut Value = getter(root);
1067                value as &mut dyn Any
1068            }),
1069            value_type_id,
1070            _phantom: PhantomData,
1071        }
1072    }
1073    
1074    /// Create a PartialWritableKeyPath from a concrete WritableKeyPath
1075    /// Alias for `new()` for consistency with `from()` pattern
1076    pub fn from<Value>(keypath: WritableKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static>) -> Self
1077    where
1078        Value: Any + 'static,
1079        Root: 'static,
1080    {
1081        Self::new(keypath)
1082    }
1083    
1084    pub fn get_mut<'r>(&self, root: &'r mut Root) -> &'r mut dyn Any {
1085        (self.getter)(root)
1086    }
1087    
1088    /// Get the TypeId of the Value type
1089    pub fn value_type_id(&self) -> TypeId {
1090        self.value_type_id
1091    }
1092    
1093    /// Try to downcast the result to a specific type
1094    pub fn get_mut_as<'a, Value: Any>(&self, root: &'a mut Root) -> Option<&'a mut Value> {
1095        if self.value_type_id == TypeId::of::<Value>() {
1096            self.get_mut(root).downcast_mut::<Value>()
1097        } else {
1098            None
1099        }
1100    }
1101}
1102
1103/// PartialWritableOptionalKeyPath - Hides the Value type but keeps Root visible (writable optional)
1104/// 
1105/// # Why PhantomData<Root>?
1106/// 
1107/// See `PartialKeyPath` documentation for explanation of why `PhantomData` is needed.
1108#[derive(Clone)]
1109pub struct PartialWritableOptionalKeyPath<Root> {
1110    getter: Rc<dyn for<'r> Fn(&'r mut Root) -> Option<&'r mut dyn Any>>,
1111    value_type_id: TypeId,
1112    _phantom: PhantomData<Root>,
1113}
1114
1115impl<Root> PartialWritableOptionalKeyPath<Root> {
1116    pub fn new<Value>(keypath: WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>) -> Self
1117    where
1118        Value: Any + 'static,
1119        Root: 'static,
1120    {
1121        let value_type_id = TypeId::of::<Value>();
1122        let getter = Rc::new(keypath.getter);
1123        
1124        Self {
1125            getter: Rc::new(move |root: &mut Root| {
1126                getter(root).map(|value: &mut Value| value as &mut dyn Any)
1127            }),
1128            value_type_id,
1129            _phantom: PhantomData,
1130        }
1131    }
1132    
1133    pub fn get_mut<'r>(&self, root: &'r mut Root) -> Option<&'r mut dyn Any> {
1134        (self.getter)(root)
1135    }
1136    
1137    /// Get the TypeId of the Value type
1138    pub fn value_type_id(&self) -> TypeId {
1139        self.value_type_id
1140    }
1141    
1142    /// Try to downcast the result to a specific type
1143    pub fn get_mut_as<'a, Value: Any>(&self, root: &'a mut Root) -> Option<Option<&'a mut Value>> {
1144        if self.value_type_id == TypeId::of::<Value>() {
1145            self.get_mut(root).map(|any| any.downcast_mut::<Value>())
1146        } else {
1147            None
1148        }
1149    }
1150}
1151
1152// ========== ANY KEYPATHS (Hide Both Root and Value Types) ==========
1153
1154/// AnyKeyPath - Hides both Root and Value types
1155/// Equivalent to Swift's AnyKeyPath
1156/// Useful for storing keypaths in collections without knowing either type
1157/// 
1158/// # Why No PhantomData?
1159/// 
1160/// Unlike `PartialKeyPath`, `AnyKeyPath` doesn't need `PhantomData` because:
1161/// - Both `Root` and `Value` types are completely erased
1162/// - We store `TypeId` instead for runtime type checking
1163/// - The type information is encoded in the closure's behavior, not the struct
1164/// - There's no generic type parameter to track at compile time
1165#[derive(Clone)]
1166pub struct AnyKeyPath {
1167    getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
1168    root_type_id: TypeId,
1169    value_type_id: TypeId,
1170}
1171
1172impl AnyKeyPath {
1173    pub fn new<Root, Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
1174    where
1175        Root: Any + 'static,
1176        Value: Any + 'static,
1177    {
1178        let root_type_id = TypeId::of::<Root>();
1179        let value_type_id = TypeId::of::<Value>();
1180        let getter = keypath.getter;
1181        
1182        Self {
1183            getter: Rc::new(move |any: &dyn Any| {
1184                if let Some(root) = any.downcast_ref::<Root>() {
1185                    getter(root).map(|value: &Value| value as &dyn Any)
1186                } else {
1187                    None
1188                }
1189            }),
1190            root_type_id,
1191            value_type_id,
1192        }
1193    }
1194    
1195    /// Create an AnyKeyPath from a concrete OptionalKeyPath
1196    /// Alias for `new()` for consistency with `from()` pattern
1197    pub fn from<Root, Value>(keypath: OptionalKeyPath<Root, Value, impl for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static>) -> Self
1198    where
1199        Root: Any + 'static,
1200        Value: Any + 'static,
1201    {
1202        Self::new(keypath)
1203    }
1204    
1205    pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
1206        (self.getter)(root)
1207    }
1208    
1209    /// Get the TypeId of the Root type
1210    pub fn root_type_id(&self) -> TypeId {
1211        self.root_type_id
1212    }
1213    
1214    /// Get the TypeId of the Value type
1215    pub fn value_type_id(&self) -> TypeId {
1216        self.value_type_id
1217    }
1218    
1219    /// Try to get the value with type checking
1220    pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
1221        if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>() {
1222            self.get(root as &dyn Any).map(|any| any.downcast_ref::<Value>())
1223        } else {
1224            None
1225        }
1226    }
1227}
1228
1229/// AnyWritableKeyPath - Hides both Root and Value types (writable)
1230#[derive(Clone)]
1231pub struct AnyWritableKeyPath {
1232    getter: Rc<dyn for<'r> Fn(&'r mut dyn Any) -> Option<&'r mut dyn Any>>,
1233    root_type_id: TypeId,
1234    value_type_id: TypeId,
1235}
1236
1237impl AnyWritableKeyPath {
1238    pub fn new<Root, Value>(keypath: WritableOptionalKeyPath<Root, Value, impl for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static>) -> Self
1239    where
1240        Root: Any + 'static,
1241        Value: Any + 'static,
1242    {
1243        let root_type_id = TypeId::of::<Root>();
1244        let value_type_id = TypeId::of::<Value>();
1245        let getter = keypath.getter;
1246        
1247        Self {
1248            getter: Rc::new(move |any: &mut dyn Any| {
1249                if let Some(root) = any.downcast_mut::<Root>() {
1250                    getter(root).map(|value: &mut Value| value as &mut dyn Any)
1251                } else {
1252                    None
1253                }
1254            }),
1255            root_type_id,
1256            value_type_id,
1257        }
1258    }
1259    
1260    pub fn get_mut<'r>(&self, root: &'r mut dyn Any) -> Option<&'r mut dyn Any> {
1261        (self.getter)(root)
1262    }
1263    
1264    /// Get the TypeId of the Root type
1265    pub fn root_type_id(&self) -> TypeId {
1266        self.root_type_id
1267    }
1268    
1269    /// Get the TypeId of the Value type
1270    pub fn value_type_id(&self) -> TypeId {
1271        self.value_type_id
1272    }
1273    
1274    /// Try to get the value with type checking
1275    pub fn get_mut_as<'a, Root: Any, Value: Any>(&self, root: &'a mut Root) -> Option<Option<&'a mut Value>> {
1276        if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>() {
1277            self.get_mut(root as &mut dyn Any).map(|any| any.downcast_mut::<Value>())
1278        } else {
1279            None
1280        }
1281    }
1282}
1283
1284// Conversion methods from concrete keypaths to partial/any keypaths
1285impl<Root, Value, F> KeyPath<Root, Value, F>
1286where
1287    F: for<'r> Fn(&'r Root) -> &'r Value + 'static,
1288    Root: 'static,
1289    Value: Any + 'static,
1290{
1291    /// Convert to PartialKeyPath (hides Value type)
1292    pub fn to_partial(self) -> PartialKeyPath<Root> {
1293        PartialKeyPath::new(self)
1294    }
1295    
1296    /// Alias for `to_partial()` - converts to PartialKeyPath
1297    pub fn to(self) -> PartialKeyPath<Root> {
1298        self.to_partial()
1299    }
1300}
1301
1302impl<Root, Value, F> OptionalKeyPath<Root, Value, F>
1303where
1304    F: for<'r> Fn(&'r Root) -> Option<&'r Value> + 'static,
1305    Root: Any + 'static,
1306    Value: Any + 'static,
1307{
1308    /// Convert to PartialOptionalKeyPath (hides Value type)
1309    pub fn to_partial(self) -> PartialOptionalKeyPath<Root> {
1310        PartialOptionalKeyPath::new(self)
1311    }
1312    
1313    /// Convert to AnyKeyPath (hides both Root and Value types)
1314    pub fn to_any(self) -> AnyKeyPath {
1315        AnyKeyPath::new(self)
1316    }
1317    
1318    /// Convert to PartialOptionalKeyPath (alias for `to_partial()`)
1319    pub fn to(self) -> PartialOptionalKeyPath<Root> {
1320        self.to_partial()
1321    }
1322}
1323
1324impl<Root, Value, F> WritableKeyPath<Root, Value, F>
1325where
1326    F: for<'r> Fn(&'r mut Root) -> &'r mut Value + 'static,
1327    Root: 'static,
1328    Value: Any + 'static,
1329{
1330    /// Convert to PartialWritableKeyPath (hides Value type)
1331    pub fn to_partial(self) -> PartialWritableKeyPath<Root> {
1332        PartialWritableKeyPath::new(self)
1333    }
1334    
1335    /// Alias for `to_partial()` - converts to PartialWritableKeyPath
1336    pub fn to(self) -> PartialWritableKeyPath<Root> {
1337        self.to_partial()
1338    }
1339}
1340
1341impl<Root, Value, F> WritableOptionalKeyPath<Root, Value, F>
1342where
1343    F: for<'r> Fn(&'r mut Root) -> Option<&'r mut Value> + 'static,
1344    Root: Any + 'static,
1345    Value: Any + 'static,
1346{
1347    /// Convert to PartialWritableOptionalKeyPath (hides Value type)
1348    pub fn to_partial(self) -> PartialWritableOptionalKeyPath<Root> {
1349        PartialWritableOptionalKeyPath::new(self)
1350    }
1351    
1352    /// Convert to AnyWritableKeyPath (hides both Root and Value types)
1353    pub fn to_any(self) -> AnyWritableKeyPath {
1354        AnyWritableKeyPath::new(self)
1355    }
1356    
1357    /// Convert to PartialWritableOptionalKeyPath (alias for `to_partial()`)
1358    pub fn to(self) -> PartialWritableOptionalKeyPath<Root> {
1359        self.to_partial()
1360    }
1361}
1362
1363#[cfg(test)]
1364mod tests {
1365    use super::*;
1366    use std::sync::atomic::{AtomicUsize, Ordering};
1367    use std::rc::Rc;
1368
1369    // Global counter to track memory allocations/deallocations
1370    static ALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
1371    static DEALLOC_COUNT: AtomicUsize = AtomicUsize::new(0);
1372
1373    // Type that panics on clone to detect unwanted cloning
1374    #[derive(Debug)]
1375    struct NoCloneType {
1376        id: usize,
1377        data: String,
1378    }
1379
1380    impl NoCloneType {
1381        fn new(data: String) -> Self {
1382            ALLOC_COUNT.fetch_add(1, Ordering::SeqCst);
1383            Self {
1384                id: ALLOC_COUNT.load(Ordering::SeqCst),
1385                data,
1386            }
1387        }
1388    }
1389
1390    impl Clone for NoCloneType {
1391        fn clone(&self) -> Self {
1392            panic!("NoCloneType should not be cloned! ID: {}", self.id);
1393        }
1394    }
1395
1396    impl Drop for NoCloneType {
1397        fn drop(&mut self) {
1398            DEALLOC_COUNT.fetch_add(1, Ordering::SeqCst);
1399        }
1400    }
1401
1402    // Helper functions for testing memory management
1403    fn reset_memory_counters() {
1404        ALLOC_COUNT.store(0, Ordering::SeqCst);
1405        DEALLOC_COUNT.store(0, Ordering::SeqCst);
1406    }
1407
1408    fn get_alloc_count() -> usize {
1409        ALLOC_COUNT.load(Ordering::SeqCst)
1410    }
1411
1412    fn get_dealloc_count() -> usize {
1413        DEALLOC_COUNT.load(Ordering::SeqCst)
1414    }
1415
1416// Usage example
1417#[derive(Debug)]
1418struct User {
1419    name: String,
1420    metadata: Option<Box<UserMetadata>>,
1421    friends: Vec<Arc<User>>,
1422}
1423
1424#[derive(Debug)]
1425struct UserMetadata {
1426    created_at: String,
1427}
1428
1429fn some_fn() {
1430        let akash = User {
1431        name: "Alice".to_string(),
1432        metadata: Some(Box::new(UserMetadata {
1433            created_at: "2024-01-01".to_string(),
1434        })),
1435        friends: vec![
1436            Arc::new(User {
1437                name: "Bob".to_string(),
1438                metadata: None,
1439                friends: vec![],
1440            }),
1441        ],
1442    };
1443    
1444    // Create keypaths
1445    let name_kp = KeyPath::new(|u: &User| &u.name);
1446    let metadata_kp = OptionalKeyPath::new(|u: &User| u.metadata.as_ref());
1447    let friends_kp = KeyPath::new(|u: &User| &u.friends);
1448    
1449    // Use them
1450        println!("Name: {}", name_kp.get(&akash));
1451    
1452        if let Some(metadata) = metadata_kp.get(&akash) {
1453        println!("Has metadata: {:?}", metadata);
1454    }
1455    
1456    // Access first friend's name
1457        if let Some(first_friend) = akash.friends.get(0) {
1458        println!("First friend: {}", name_kp.get(first_friend));
1459    }
1460    
1461        // Access metadata through Box using for_box()
1462    let created_at_kp = KeyPath::new(|m: &UserMetadata| &m.created_at);
1463    
1464        if let Some(metadata) = akash.metadata.as_ref() {
1465            // Use for_box() to unwrap Box<UserMetadata> to &UserMetadata
1466            let boxed_metadata: &Box<UserMetadata> = metadata;
1467            let unwrapped = boxed_metadata.as_ref();
1468            println!("Created at: {:?}", created_at_kp.get(unwrapped));
1469        }
1470    }
1471
1472    #[test]
1473    fn test_name() {
1474        some_fn();
1475    }
1476    
1477    #[test]
1478    fn test_no_cloning_on_keypath_operations() {
1479        reset_memory_counters();
1480        
1481        // Create a value that panics on clone
1482        let value = NoCloneType::new("test".to_string());
1483        let boxed = Box::new(value);
1484        
1485        // Create keypath - should not clone
1486        let kp = KeyPath::new(|b: &Box<NoCloneType>| b.as_ref());
1487        
1488        // Access value - should not clone
1489        let _ref = kp.get(&boxed);
1490        
1491        // Clone the keypath itself (this is allowed)
1492        let _kp_clone = kp.clone();
1493        
1494        // Access again - should not clone the value
1495        let _ref2 = _kp_clone.get(&boxed);
1496        
1497        // Verify no panics occurred (if we got here, no cloning happened)
1498        assert_eq!(get_alloc_count(), 1);
1499    }
1500    
1501    #[test]
1502    fn test_no_cloning_on_optional_keypath_operations() {
1503        reset_memory_counters();
1504        
1505        let value = NoCloneType::new("test".to_string());
1506        let opt = Some(Box::new(value));
1507        
1508        // Create optional keypath
1509        let okp = OptionalKeyPath::new(|o: &Option<Box<NoCloneType>>| o.as_ref());
1510        
1511        // Access - should not clone
1512        let _ref = okp.get(&opt);
1513        
1514        // Clone keypath (allowed)
1515        let _okp_clone = okp.clone();
1516        
1517        // Chain operations - should not clone values
1518        let chained = okp.then(OptionalKeyPath::new(|b: &Box<NoCloneType>| Some(b.as_ref())));
1519        let _ref2 = chained.get(&opt);
1520        
1521        assert_eq!(get_alloc_count(), 1);
1522    }
1523    
1524    #[test]
1525    fn test_memory_release() {
1526        reset_memory_counters();
1527        
1528        {
1529            let value = NoCloneType::new("test".to_string());
1530            let boxed = Box::new(value);
1531            let kp = KeyPath::new(|b: &Box<NoCloneType>| b.as_ref());
1532            
1533            // Use the keypath
1534            let _ref = kp.get(&boxed);
1535            
1536            // boxed goes out of scope here
1537        }
1538        
1539        // After drop, memory should be released
1540        // Note: This is a best-effort check since drop timing can vary
1541        assert_eq!(get_alloc_count(), 1);
1542        // Deallocation happens when the value is dropped
1543        // We can't reliably test exact timing, but we verify the counter exists
1544    }
1545    
1546    #[test]
1547    fn test_keypath_clone_does_not_clone_underlying_data() {
1548        reset_memory_counters();
1549        
1550        let value = NoCloneType::new("data".to_string());
1551        let rc_value = Rc::new(value);
1552        
1553        // Create keypath
1554        let kp = KeyPath::new(|r: &Rc<NoCloneType>| r.as_ref());
1555        
1556        // Clone keypath multiple times
1557        let kp1 = kp.clone();
1558        let kp2 = kp.clone();
1559        let kp3 = kp1.clone();
1560        
1561        // All should work without cloning the underlying data
1562        let _ref1 = kp.get(&rc_value);
1563        let _ref2 = kp1.get(&rc_value);
1564        let _ref3 = kp2.get(&rc_value);
1565        let _ref4 = kp3.get(&rc_value);
1566        
1567        // Only one allocation should have happened
1568        assert_eq!(get_alloc_count(), 1);
1569    }
1570    
1571    #[test]
1572    fn test_optional_keypath_chaining_no_clone() {
1573        reset_memory_counters();
1574        
1575        let value = NoCloneType::new("value1".to_string());
1576        
1577        struct Container {
1578            inner: Option<Box<NoCloneType>>,
1579        }
1580        
1581        let container = Container {
1582            inner: Some(Box::new(value)),
1583        };
1584        
1585        // Create chained keypath
1586        let kp1 = OptionalKeyPath::new(|c: &Container| c.inner.as_ref());
1587        let kp2 = OptionalKeyPath::new(|b: &Box<NoCloneType>| Some(b.as_ref()));
1588        
1589        // Chain them - should not clone
1590        let chained = kp1.then(kp2);
1591        
1592        // Use chained keypath
1593        let _result = chained.get(&container);
1594        
1595        // Should only have one allocation
1596        assert_eq!(get_alloc_count(), 1);
1597    }
1598    
1599    #[test]
1600    fn test_for_box_no_clone() {
1601        reset_memory_counters();
1602        
1603        let value = NoCloneType::new("test".to_string());
1604        let boxed = Box::new(value);
1605        let opt_boxed = Some(boxed);
1606        
1607        // Create keypath with for_box
1608        let kp = OptionalKeyPath::new(|o: &Option<Box<NoCloneType>>| o.as_ref());
1609        let unwrapped = kp.for_box();
1610        
1611        // Access - should not clone
1612        let _ref = unwrapped.get(&opt_boxed);
1613        
1614        assert_eq!(get_alloc_count(), 1);
1615    }
1616}