rust_keypaths/
lib.rs

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