Skip to main content

rust_key_paths/
lib.rs

1// pub type KpType<R, V, Root, Value, MutRoot, MutValue, G, S>
2// where
3//     Root: ,
4//     Value:    Borrow<V>,
5//     MutRoot:  BorrowMut<R>,
6//     MutValue: std::borrow::BorrowMut<V>,
7//     G:        Fn(Root) -> Option<Value>,
8//     S:        Fn(MutRoot) -> Option<MutValue> = Kp<R, V, Root, Value, MutRoot, MutValue, G, S>;
9
10// type Getter<R, V, Root, Value> where Root: std::borrow::Borrow<R>, Value: std::borrow::Borrow<V> = fn(Root) -> Option<Value>;
11// type Setter<R, V> = fn(&'r mut R) -> Option<&'r mut V>;
12
13use std::sync::{Arc, Mutex};
14
15// Export the lock module
16pub mod lock;
17pub use lock::{
18    ArcMutexAccess, ArcRwLockAccess, LockAccess, LockKp, LockKpType, RcRefCellAccess,
19    StdMutexAccess, StdRwLockAccess,
20};
21
22#[cfg(feature = "parking_lot")]
23pub use lock::{
24    DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
25    ParkingLotRwLockAccess,
26};
27
28// Export the async_lock module
29pub mod async_lock;
30
31/// Used so that `then_async` can infer `V2` from `AsyncKp::Value` without ambiguity
32/// (e.g. `&i32` has both `Borrow<i32>` and `Borrow<&i32>`; this picks the referent).
33/// Implemented only for reference types so there is no overlap with the blanket impl.
34pub trait KeyPathValueTarget {
35    type Target: Sized;
36}
37impl<T> KeyPathValueTarget for &T {
38    type Target = T;
39}
40impl<T> KeyPathValueTarget for &mut T {
41    type Target = T;
42}
43
44pub type KpDynamic<R, V> = Kp<
45    R,
46    V,
47    &'static R,
48    &'static V,
49    &'static mut R,
50    &'static mut V,
51    Box<dyn for<'a> Fn(&'a R) -> Option<&'a V>>,
52    Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V>>,
53>;
54
55pub type KpType<'a, R, V> = Kp<
56    R,
57    V,
58    &'a R,
59    &'a V,
60    &'a mut R,
61    &'a mut V,
62    for<'b> fn(&'b R) -> Option<&'b V>,
63    for<'b> fn(&'b mut R) -> Option<&'b mut V>,
64>;
65
66// pub type KpType<R, V> = Kp<
67//     R,
68//     V,
69//     &'static R,
70//     &'static V,
71//     &'static mut R,
72//     &'static mut V,
73//     for<'a> fn(&'a R) -> Option<&'a V>,
74//     for<'a> fn(&'a mut R) -> Option<&'a mut V>,
75// >;
76
77// struct A{
78//     b: std::sync::Arc<std::sync::Mutex<B>>,
79// }
80// struct B{
81//     c: C
82// }
83// struct C{
84//     d: String
85// }
86
87// pub struct LockKp {
88//     first: KpType<'static, A, B>,
89//     mid: KpType<'static, std::sync::Mutex<B>, B>,
90//     second: KpType<'static, B, C>,
91// }
92//
93// impl LockKp {
94//     fn then(&self, kp: KpType<'static, B, String>) {
95//
96//     }
97//     fn then_lock() {}
98// }
99
100// New type alias for composed/transformed keypaths
101pub type KpComposed<R, V> = Kp<
102    R,
103    V,
104    &'static R,
105    &'static V,
106    &'static mut R,
107    &'static mut V,
108    Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>,
109    Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>,
110>;
111
112impl<R, V> Kp<
113    R,
114    V,
115    &'static R,
116    &'static V,
117    &'static mut R,
118    &'static mut V,
119    Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>,
120    Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>,
121> {
122    /// Build a keypath from two closures (e.g. when they capture a variable like an index).
123    /// Same pattern as `Kp::new` in lock.rs; use this when the keypath captures variables.
124    pub fn from_closures<G, S>(get: G, set: S) -> Self
125    where
126        G: for<'b> Fn(&'b R) -> Option<&'b V> + 'static,
127        S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + 'static,
128    {
129        Self::new(Box::new(get), Box::new(set))
130    }
131}
132
133pub struct AKp {
134    getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
135    root_type_id: TypeId,
136    value_type_id: TypeId,
137}
138
139impl AKp {
140    /// Create a new AKp from a KpType (the common reference-based keypath)
141    pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
142    where
143        R: Any + 'static,
144        V: Any + 'static,
145    {
146        let root_type_id = TypeId::of::<R>();
147        let value_type_id = TypeId::of::<V>();
148        let getter_fn = keypath.get;
149
150        Self {
151            getter: Rc::new(move |any: &dyn Any| {
152                if let Some(root) = any.downcast_ref::<R>() {
153                    getter_fn(root).map(|value: &V| value as &dyn Any)
154                } else {
155                    None
156                }
157            }),
158            root_type_id,
159            value_type_id,
160        }
161    }
162
163    /// Create an AKp from a KpType (alias for `new()`)
164    pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
165    where
166        R: Any + 'static,
167        V: Any + 'static,
168    {
169        Self::new(keypath)
170    }
171
172    /// Get the value as a trait object (with root type checking)
173    pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
174        (self.getter)(root)
175    }
176
177    /// Get the TypeId of the Root type
178    pub fn root_type_id(&self) -> TypeId {
179        self.root_type_id
180    }
181
182    /// Get the TypeId of the Value type
183    pub fn value_type_id(&self) -> TypeId {
184        self.value_type_id
185    }
186
187    /// Try to get the value with full type checking
188    pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
189        if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
190        {
191            Some(
192                self.get(root as &dyn Any)
193                    .and_then(|any| any.downcast_ref::<Value>()),
194            )
195        } else {
196            None
197        }
198    }
199
200    /// Get a human-readable name for the value type
201    pub fn kind_name(&self) -> String {
202        format!("{:?}", self.value_type_id)
203    }
204
205    /// Get a human-readable name for the root type
206    pub fn root_kind_name(&self) -> String {
207        format!("{:?}", self.root_type_id)
208    }
209
210    /// Adapt this keypath to work with Arc<Root> instead of Root
211    pub fn for_arc<Root>(&self) -> AKp
212    where
213        Root: Any + 'static,
214    {
215        let value_type_id = self.value_type_id;
216        let getter = self.getter.clone();
217
218        AKp {
219            getter: Rc::new(move |any: &dyn Any| {
220                if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
221                    getter(arc.as_ref() as &dyn Any)
222                } else {
223                    None
224                }
225            }),
226            root_type_id: TypeId::of::<Arc<Root>>(),
227            value_type_id,
228        }
229    }
230
231    /// Adapt this keypath to work with Box<Root> instead of Root
232    pub fn for_box<Root>(&self) -> AKp
233    where
234        Root: Any + 'static,
235    {
236        let value_type_id = self.value_type_id;
237        let getter = self.getter.clone();
238
239        AKp {
240            getter: Rc::new(move |any: &dyn Any| {
241                if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
242                    getter(boxed.as_ref() as &dyn Any)
243                } else {
244                    None
245                }
246            }),
247            root_type_id: TypeId::of::<Box<Root>>(),
248            value_type_id,
249        }
250    }
251
252    /// Adapt this keypath to work with Rc<Root> instead of Root
253    pub fn for_rc<Root>(&self) -> AKp
254    where
255        Root: Any + 'static,
256    {
257        let value_type_id = self.value_type_id;
258        let getter = self.getter.clone();
259
260        AKp {
261            getter: Rc::new(move |any: &dyn Any| {
262                if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
263                    getter(rc.as_ref() as &dyn Any)
264                } else {
265                    None
266                }
267            }),
268            root_type_id: TypeId::of::<Rc<Root>>(),
269            value_type_id,
270        }
271    }
272
273    /// Adapt this keypath to work with Option<Root> instead of Root
274    pub fn for_option<Root>(&self) -> AKp
275    where
276        Root: Any + 'static,
277    {
278        let value_type_id = self.value_type_id;
279        let getter = self.getter.clone();
280
281        AKp {
282            getter: Rc::new(move |any: &dyn Any| {
283                if let Some(opt) = any.downcast_ref::<Option<Root>>() {
284                    opt.as_ref().and_then(|root| getter(root as &dyn Any))
285                } else {
286                    None
287                }
288            }),
289            root_type_id: TypeId::of::<Option<Root>>(),
290            value_type_id,
291        }
292    }
293
294    /// Adapt this keypath to work with Result<Root, E> instead of Root
295    pub fn for_result<Root, E>(&self) -> AKp
296    where
297        Root: Any + 'static,
298        E: Any + 'static,
299    {
300        let value_type_id = self.value_type_id;
301        let getter = self.getter.clone();
302
303        AKp {
304            getter: Rc::new(move |any: &dyn Any| {
305                if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
306                    result
307                        .as_ref()
308                        .ok()
309                        .and_then(|root| getter(root as &dyn Any))
310                } else {
311                    None
312                }
313            }),
314            root_type_id: TypeId::of::<Result<Root, E>>(),
315            value_type_id,
316        }
317    }
318
319    /// Map the value through a transformation function with type checking
320    /// Both original and mapped values must implement Any
321    ///
322    /// # Example
323    /// ```
324    /// use rust_key_paths::{AKp, Kp, KpType};
325    /// struct User { name: String }
326    /// let user = User { name: "Alice".to_string() };
327    /// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
328    /// let name_akp = AKp::new(name_kp);
329    /// let len_akp = name_akp.map::<User, String, _, _>(|s| s.len());
330    /// ```
331    pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
332    where
333        Root: Any + 'static,
334        OrigValue: Any + 'static,
335        MappedValue: Any + 'static,
336        F: Fn(&OrigValue) -> MappedValue + 'static,
337    {
338        let orig_root_type_id = self.root_type_id;
339        let orig_value_type_id = self.value_type_id;
340        let getter = self.getter.clone();
341        let mapped_type_id = TypeId::of::<MappedValue>();
342
343        AKp {
344            getter: Rc::new(move |any_root: &dyn Any| {
345                // Check root type matches
346                if any_root.type_id() == orig_root_type_id {
347                    getter(any_root).and_then(|any_value| {
348                        // Verify the original value type matches
349                        if orig_value_type_id == TypeId::of::<OrigValue>() {
350                            any_value.downcast_ref::<OrigValue>().map(|orig_val| {
351                                let mapped = mapper(orig_val);
352                                // Box the mapped value and return as &dyn Any
353                                Box::leak(Box::new(mapped)) as &dyn Any
354                            })
355                        } else {
356                            None
357                        }
358                    })
359                } else {
360                    None
361                }
362            }),
363            root_type_id: orig_root_type_id,
364            value_type_id: mapped_type_id,
365        }
366    }
367
368    /// Filter the value based on a predicate with full type checking
369    /// Returns None if types don't match or predicate fails
370    ///
371    /// # Example
372    /// ```
373    /// use rust_key_paths::{AKp, Kp, KpType};
374    /// struct User { age: i32 }
375    /// let user = User { age: 30 };
376    /// let age_kp = KpType::new(|u: &User| Some(&u.age), |_| None);
377    /// let age_akp = AKp::new(age_kp);
378    /// let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
379    /// ```
380    pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
381    where
382        Root: Any + 'static,
383        Value: Any + 'static,
384        F: Fn(&Value) -> bool + 'static,
385    {
386        let orig_root_type_id = self.root_type_id;
387        let orig_value_type_id = self.value_type_id;
388        let getter = self.getter.clone();
389
390        AKp {
391            getter: Rc::new(move |any_root: &dyn Any| {
392                // Check root type matches
393                if any_root.type_id() == orig_root_type_id {
394                    getter(any_root).filter(|any_value| {
395                        // Type check value and apply predicate
396                        if orig_value_type_id == TypeId::of::<Value>() {
397                            any_value
398                                .downcast_ref::<Value>()
399                                .map(|val| predicate(val))
400                                .unwrap_or(false)
401                        } else {
402                            false
403                        }
404                    })
405                } else {
406                    None
407                }
408            }),
409            root_type_id: orig_root_type_id,
410            value_type_id: orig_value_type_id,
411        }
412    }
413}
414pub struct PKp<Root> {
415    getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
416    value_type_id: TypeId,
417    _phantom: std::marker::PhantomData<Root>,
418}
419
420impl<Root> PKp<Root>
421where
422    Root: 'static,
423{
424    /// Create a new PKp from a KpType (the common reference-based keypath)
425    pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
426    where
427        V: Any + 'static,
428    {
429        let value_type_id = TypeId::of::<V>();
430        let getter_fn = keypath.get;
431
432        Self {
433            getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
434            value_type_id,
435            _phantom: std::marker::PhantomData,
436        }
437    }
438
439    /// Create a PKp from a KpType (alias for `new()`)
440    pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
441    where
442        V: Any + 'static,
443    {
444        Self::new(keypath)
445    }
446
447    /// Get the value as a trait object
448    pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
449        (self.getter)(root)
450    }
451
452    /// Get the TypeId of the Value type
453    pub fn value_type_id(&self) -> TypeId {
454        self.value_type_id
455    }
456
457    /// Try to downcast the result to a specific type
458    pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
459        if self.value_type_id == TypeId::of::<Value>() {
460            self.get(root).and_then(|any| any.downcast_ref::<Value>())
461        } else {
462            None
463        }
464    }
465
466    /// Get a human-readable name for the value type
467    pub fn kind_name(&self) -> String {
468        format!("{:?}", self.value_type_id)
469    }
470
471    /// Adapt this keypath to work with Arc<Root> instead of Root
472    pub fn for_arc(&self) -> PKp<Arc<Root>> {
473        let getter = self.getter.clone();
474        let value_type_id = self.value_type_id;
475
476        PKp {
477            getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
478            value_type_id,
479            _phantom: std::marker::PhantomData,
480        }
481    }
482
483    /// Adapt this keypath to work with Box<Root> instead of Root
484    pub fn for_box(&self) -> PKp<Box<Root>> {
485        let getter = self.getter.clone();
486        let value_type_id = self.value_type_id;
487
488        PKp {
489            getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
490            value_type_id,
491            _phantom: std::marker::PhantomData,
492        }
493    }
494
495    /// Adapt this keypath to work with Rc<Root> instead of Root
496    pub fn for_rc(&self) -> PKp<Rc<Root>> {
497        let getter = self.getter.clone();
498        let value_type_id = self.value_type_id;
499
500        PKp {
501            getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
502            value_type_id,
503            _phantom: std::marker::PhantomData,
504        }
505    }
506
507    /// Adapt this keypath to work with Option<Root> instead of Root
508    pub fn for_option(&self) -> PKp<Option<Root>> {
509        let getter = self.getter.clone();
510        let value_type_id = self.value_type_id;
511
512        PKp {
513            getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
514            value_type_id,
515            _phantom: std::marker::PhantomData,
516        }
517    }
518
519    /// Adapt this keypath to work with Result<Root, E> instead of Root
520    pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
521    where
522        E: 'static,
523    {
524        let getter = self.getter.clone();
525        let value_type_id = self.value_type_id;
526
527        PKp {
528            getter: Rc::new(move |result: &Result<Root, E>| {
529                result.as_ref().ok().and_then(|root| getter(root))
530            }),
531            value_type_id,
532            _phantom: std::marker::PhantomData,
533        }
534    }
535
536    /// Map the value through a transformation function
537    /// The mapped value must also implement Any for type erasure
538    ///
539    /// # Example
540    /// ```
541    /// use rust_key_paths::{Kp, KpType, PKp};
542    /// struct User { name: String }
543    /// let user = User { name: "Alice".to_string() };
544    /// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
545    /// let name_pkp = PKp::new(name_kp);
546    /// let len_pkp = name_pkp.map::<String, _, _>(|s| s.len());
547    /// assert_eq!(len_pkp.get_as::<usize>(&user), Some(&5));
548    /// ```
549    pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
550    where
551        OrigValue: Any + 'static,
552        MappedValue: Any + 'static,
553        F: Fn(&OrigValue) -> MappedValue + 'static,
554    {
555        let orig_type_id = self.value_type_id;
556        let getter = self.getter.clone();
557        let mapped_type_id = TypeId::of::<MappedValue>();
558
559        PKp {
560            getter: Rc::new(move |root: &Root| {
561                getter(root).and_then(|any_value| {
562                    // Verify the original type matches
563                    if orig_type_id == TypeId::of::<OrigValue>() {
564                        any_value.downcast_ref::<OrigValue>().map(|orig_val| {
565                            let mapped = mapper(orig_val);
566                            // Box the mapped value and return as &dyn Any
567                            // Note: This creates a new allocation
568                            Box::leak(Box::new(mapped)) as &dyn Any
569                        })
570                    } else {
571                        None
572                    }
573                })
574            }),
575            value_type_id: mapped_type_id,
576            _phantom: std::marker::PhantomData,
577        }
578    }
579
580    /// Filter the value based on a predicate with type checking
581    /// Returns None if the type doesn't match or predicate fails
582    ///
583    /// # Example
584    /// ```
585    /// use rust_key_paths::{Kp, KpType, PKp};
586    /// struct User { age: i32 }
587    /// let user = User { age: 30 };
588    /// let age_kp = KpType::new(|u: &User| Some(&u.age), |_| None);
589    /// let age_pkp = PKp::new(age_kp);
590    /// let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
591    /// assert_eq!(adult_pkp.get_as::<i32>(&user), Some(&30));
592    /// ```
593    pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
594    where
595        Value: Any + 'static,
596        F: Fn(&Value) -> bool + 'static,
597    {
598        let orig_type_id = self.value_type_id;
599        let getter = self.getter.clone();
600
601        PKp {
602            getter: Rc::new(move |root: &Root| {
603                getter(root).filter(|any_value| {
604                    // Type check and apply predicate
605                    if orig_type_id == TypeId::of::<Value>() {
606                        any_value
607                            .downcast_ref::<Value>()
608                            .map(|val| predicate(val))
609                            .unwrap_or(false)
610                    } else {
611                        false
612                    }
613                })
614            }),
615            value_type_id: orig_type_id,
616            _phantom: std::marker::PhantomData,
617        }
618    }
619}
620
621// ========== ANY KEYPATHS (Hide Both Root and Value Types) ==========
622
623/// AKp (AnyKeyPath) - Hides both Root and Value types
624/// Most flexible keypath type for heterogeneous collections
625/// Uses dynamic dispatch and type checking at runtime
626///
627/// # Mutation: get vs get_mut (setter path)
628///
629/// - **[get](Kp::get)** uses the `get` closure (getter): `Fn(Root) -> Option<Value>`
630/// - **[get_mut](Kp::get_mut)** uses the `set` closure (setter): `Fn(MutRoot) -> Option<MutValue>`
631///
632/// When mutating through a Kp, the **setter path** is used—`get_mut` invokes the `set` closure,
633/// not the `get` closure. The getter is for read-only access only.
634#[derive(Clone)]
635pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
636where
637    Root: std::borrow::Borrow<R>,
638    MutRoot: std::borrow::BorrowMut<R>,
639    MutValue: std::borrow::BorrowMut<V>,
640    G: Fn(Root) -> Option<Value>,
641    S: Fn(MutRoot) -> Option<MutValue>,
642{
643    /// Getter closure: used by [Kp::get] for read-only access.
644    pub(crate) get: G,
645    /// Setter closure: used by [Kp::get_mut] for mutation.
646    pub(crate) set: S,
647    _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
648}
649
650impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
651where
652    Root: std::borrow::Borrow<R>,
653    Value: std::borrow::Borrow<V>,
654    MutRoot: std::borrow::BorrowMut<R>,
655    MutValue: std::borrow::BorrowMut<V>,
656    G: Fn(Root) -> Option<Value>,
657    S: Fn(MutRoot) -> Option<MutValue>,
658{
659    pub fn new(get: G, set: S) -> Self {
660        Self {
661            get: get,
662            set: set,
663            _p: std::marker::PhantomData,
664        }
665    }
666
667    #[inline]
668    pub fn get(&self, root: Root) -> Option<Value> {
669        (self.get)(root)
670    }
671    #[inline]
672    pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
673        (self.set)(root)
674    }
675
676    pub fn then<SV, SubValue, MutSubValue, G2, S2>(
677        self,
678        next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
679    ) -> Kp<
680        R,
681        SV,
682        Root,
683        SubValue,
684        MutRoot,
685        MutSubValue,
686        impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
687        impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>,
688    >
689    where
690        SubValue: std::borrow::Borrow<SV>,
691        MutSubValue: std::borrow::BorrowMut<SV>,
692        G2: Fn(Value) -> Option<SubValue>,
693        S2: Fn(MutValue) -> Option<MutSubValue>,
694        V: 'static,
695    {
696        Kp::new(
697            move |root: Root| (self.get)(root).and_then(|value| (next.get)(value)),
698            move |root: MutRoot| (self.set)(root).and_then(|value| (next.set)(value)),
699        )
700    }
701
702    /// Chain with a sync [crate::lock::LockKp]. Use `.get(root)` / `.get_mut(root)` on the returned keypath.
703    pub fn then_lock<
704        Lock,
705        Mid,
706        V2,
707        LockValue,
708        MidValue,
709        Value2,
710        MutLock,
711        MutMid,
712        MutValue2,
713        G1,
714        S1,
715        L,
716        G2,
717        S2,
718    >(
719        self,
720        lock_kp: crate::lock::LockKp<
721            V,
722            Lock,
723            Mid,
724            V2,
725            Value,
726            LockValue,
727            MidValue,
728            Value2,
729            MutValue,
730            MutLock,
731            MutMid,
732            MutValue2,
733            G1,
734            S1,
735            L,
736            G2,
737            S2,
738        >,
739    ) -> crate::lock::KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, Self, crate::lock::LockKp<V, Lock, Mid, V2, Value, LockValue, MidValue, Value2, MutValue, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>>
740    where
741        V: 'static + Clone,
742        V2: 'static,
743        Value: std::borrow::Borrow<V>,
744        Value2: std::borrow::Borrow<V2>,
745        MutValue: std::borrow::BorrowMut<V>,
746        MutValue2: std::borrow::BorrowMut<V2>,
747        LockValue: std::borrow::Borrow<Lock>,
748        MidValue: std::borrow::Borrow<Mid>,
749        MutLock: std::borrow::BorrowMut<Lock>,
750        MutMid: std::borrow::BorrowMut<Mid>,
751        G1: Fn(Value) -> Option<LockValue>,
752        S1: Fn(MutValue) -> Option<MutLock>,
753        L: crate::lock::LockAccess<Lock, MidValue> + crate::lock::LockAccess<Lock, MutMid>,
754        G2: Fn(MidValue) -> Option<Value2>,
755        S2: Fn(MutMid) -> Option<MutValue2>,
756    {
757        crate::lock::KpThenLockKp {
758            first: self,
759            second: lock_kp,
760            _p: std::marker::PhantomData,
761        }
762    }
763
764    /// Chain with an async keypath (e.g. [crate::async_lock::AsyncLockKp]). Use `.get(&root).await` on the returned keypath.
765    /// When `AsyncKp::Value` is a reference type (`&T` / `&mut T`), `V2` is inferred as `T` via [KeyPathValueTarget].
766    pub fn then_async<AsyncKp>(
767        self,
768        async_kp: AsyncKp,
769    ) -> crate::async_lock::KpThenAsyncKeyPath<
770        R,
771        V,
772        <AsyncKp::Value as KeyPathValueTarget>::Target,
773        Root,
774        Value,
775        AsyncKp::Value,
776        MutRoot,
777        MutValue,
778        AsyncKp::MutValue,
779        Self,
780        AsyncKp,
781    >
782    where
783        V: 'static,
784        Value: std::borrow::Borrow<V>,
785        MutValue: std::borrow::BorrowMut<V>,
786        AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
787        AsyncKp::Value: KeyPathValueTarget
788            + std::borrow::Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>,
789        AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>,
790        <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,
791    {
792        crate::async_lock::KpThenAsyncKeyPath {
793            first: self,
794            second: async_kp,
795            _p: std::marker::PhantomData,
796        }
797    }
798
799    /// Map the value through a transformation function
800    /// Returns a new keypath that transforms the value when accessed
801    ///
802    /// # Example
803    /// ```
804    /// use rust_key_paths::{Kp, KpType};
805    /// struct User { name: String }
806    /// let user = User { name: "Alice".to_string() };
807    /// let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
808    /// let len_kp = name_kp.map(|name: &String| name.len());
809    /// assert_eq!(len_kp.get(&user), Some(5));
810    /// ```
811    pub fn map<MappedValue, F>(
812        &self,
813        mapper: F,
814    ) -> Kp<
815        R,
816        MappedValue,
817        Root,
818        MappedValue,
819        MutRoot,
820        MappedValue,
821        impl Fn(Root) -> Option<MappedValue>,
822        impl Fn(MutRoot) -> Option<MappedValue>,
823    >
824    where
825        // Copy: Required because mapper is used in both getter and setter closures
826        // 'static: Required because the returned Kp must own its closures
827        F: Fn(&V) -> MappedValue + Copy + 'static,
828        V: 'static,
829        MappedValue: 'static,
830    {
831        Kp::new(
832            move |root: Root| {
833                (&self.get)(root).map(|value| {
834                    let v: &V = value.borrow();
835                    mapper(v)
836                })
837            },
838            move |root: MutRoot| {
839                (&self.set)(root).map(|value| {
840                    let v: &V = value.borrow();
841                    mapper(v)
842                })
843            },
844        )
845    }
846
847    /// Filter the value based on a predicate
848    /// Returns None if the predicate returns false, otherwise returns the value
849    ///
850    /// # Example
851    /// ```
852    /// use rust_key_paths::{Kp, KpType};
853    /// struct User { age: i32 }
854    /// let user = User { age: 30 };
855    /// let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
856    /// let adult_kp = age_kp.filter(|age: &i32| *age >= 18);
857    /// assert_eq!(adult_kp.get(&user), Some(&30));
858    /// ```
859    pub fn filter<F>(
860        &self,
861        predicate: F,
862    ) -> Kp<
863        R,
864        V,
865        Root,
866        Value,
867        MutRoot,
868        MutValue,
869        impl Fn(Root) -> Option<Value>,
870        impl Fn(MutRoot) -> Option<MutValue>,
871    >
872    where
873        // Copy: Required because predicate is used in both getter and setter closures
874        // 'static: Required because the returned Kp must own its closures
875        F: Fn(&V) -> bool + Copy + 'static,
876        V: 'static,
877    {
878        Kp::new(
879            move |root: Root| {
880                (&self.get)(root).filter(|value| {
881                    let v: &V = value.borrow();
882                    predicate(v)
883                })
884            },
885            move |root: MutRoot| {
886                (&self.set)(root).filter(|value| {
887                    let v: &V = value.borrow();
888                    predicate(v)
889                })
890            },
891        )
892    }
893
894    /// Map and flatten - useful when mapper returns an Option
895    ///
896    /// # Example
897    /// ```
898    /// use rust_key_paths::{Kp, KpType};
899    /// struct User { middle_name: Option<String> }
900    /// let user = User { middle_name: Some("M.".to_string()) };
901    /// let middle_kp = KpType::new(|u: &User| Some(&u.middle_name), |_| None);
902    /// let first_char_kp = middle_kp.filter_map(|opt: &Option<String>| {
903    ///     opt.as_ref().and_then(|s| s.chars().next())
904    /// });
905    /// ```
906    pub fn filter_map<MappedValue, F>(
907        &self,
908        mapper: F,
909    ) -> Kp<
910        R,
911        MappedValue,
912        Root,
913        MappedValue,
914        MutRoot,
915        MappedValue,
916        impl Fn(Root) -> Option<MappedValue>,
917        impl Fn(MutRoot) -> Option<MappedValue>,
918    >
919    where
920        // Copy: Required because mapper is used in both getter and setter closures
921        // 'static: Required because the returned Kp must own its closures
922        F: Fn(&V) -> Option<MappedValue> + Copy + 'static,
923        V: 'static,
924        MappedValue: 'static,
925    {
926        Kp::new(
927            move |root: Root| {
928                (&self.get)(root).and_then(|value| {
929                    let v: &V = value.borrow();
930                    mapper(v)
931                })
932            },
933            move |root: MutRoot| {
934                (&self.set)(root).and_then(|value| {
935                    let v: &V = value.borrow();
936                    mapper(v)
937                })
938            },
939        )
940    }
941
942    /// Flat map - maps to an iterator and flattens
943    /// Useful when the value is a collection and you want to iterate over it
944    ///
945    /// # Example
946    /// ```
947    /// use rust_key_paths::{Kp, KpType};
948    /// struct User { tags: Vec<&'static str> }
949    /// let user = User { tags: vec!["rust", "web"] };
950    /// let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
951    /// // Use with a closure that returns an iterator
952    /// ```
953    pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
954    where
955        // No Copy needed - mapper is only captured once by the returned closure
956        // 'static: Required so the returned function can outlive the call
957        F: Fn(&V) -> I + 'static,
958        V: 'static,
959        I: IntoIterator<Item = Item>,
960        Item: 'static,
961    {
962        move |root: Root| {
963            (&self.get)(root)
964                .map(|value| {
965                    let v: &V = value.borrow();
966                    mapper(v).into_iter().collect()
967                })
968                .unwrap_or_else(Vec::new)
969        }
970    }
971
972    /// Apply a function for its side effects and return the value
973    ///
974    /// # Example
975    /// ```
976    /// use rust_key_paths::{Kp, KpType};
977    /// struct User { name: String }
978    /// let user = User { name: "Alice".to_string() };
979    /// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
980    /// name_kp.inspect(|name| println!("Name: {}", name)).get(&user);
981    /// ```
982    pub fn inspect<F>(
983        &self,
984        inspector: F,
985    ) -> Kp<
986        R,
987        V,
988        Root,
989        Value,
990        MutRoot,
991        MutValue,
992        impl Fn(Root) -> Option<Value>,
993        impl Fn(MutRoot) -> Option<MutValue>,
994    >
995    where
996        // Copy: Required because inspector is used in both getter and setter closures
997        // 'static: Required because the returned Kp must own its closures
998        F: Fn(&V) + Copy + 'static,
999        V: 'static,
1000    {
1001        Kp::new(
1002            move |root: Root| {
1003                (&self.get)(root).map(|value| {
1004                    let v: &V = value.borrow();
1005                    inspector(v);
1006                    value
1007                })
1008            },
1009            move |root: MutRoot| {
1010                (&self.set)(root).map(|value| {
1011                    let v: &V = value.borrow();
1012                    inspector(v);
1013                    value
1014                })
1015            },
1016        )
1017    }
1018
1019    /// Fold/reduce the value using an accumulator function
1020    /// Useful when the value is a collection
1021    ///
1022    /// # Example
1023    /// ```
1024    /// use rust_key_paths::{Kp, KpType};
1025    /// struct User { scores: Vec<i32> }
1026    /// let user = User { scores: vec![85, 92, 78] };
1027    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1028    /// let sum = scores_kp.fold_value(0, |acc, scores| {
1029    ///     scores.iter().sum::<i32>() + acc
1030    /// })(&user);
1031    /// ```
1032    pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
1033    where
1034        // No Copy needed - folder is only captured once by the returned closure
1035        // 'static: Required so the returned function can outlive the call
1036        F: Fn(Acc, &V) -> Acc + 'static,
1037        V: 'static,
1038        // Copy: Required for init since it's returned as default value
1039        Acc: Copy + 'static,
1040    {
1041        move |root: Root| {
1042            (&self.get)(root)
1043                .map(|value| {
1044                    let v: &V = value.borrow();
1045                    folder(init, v)
1046                })
1047                .unwrap_or(init)
1048        }
1049    }
1050
1051    /// Check if any element satisfies a predicate (for collection values)
1052    ///
1053    /// # Example
1054    /// ```
1055    /// use rust_key_paths::{Kp, KpType};
1056    /// struct User { scores: Vec<i32> }
1057    /// let user = User { scores: vec![85, 92, 78] };
1058    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1059    /// let has_high = scores_kp.any(|scores| scores.iter().any(|&s| s > 90));
1060    /// assert!(has_high(&user));
1061    /// ```
1062    pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1063    where
1064        // No Copy needed - predicate is only captured once by the returned closure
1065        // 'static: Required so the returned function can outlive the call
1066        F: Fn(&V) -> bool + 'static,
1067        V: 'static,
1068    {
1069        move |root: Root| {
1070            (&self.get)(root)
1071                .map(|value| {
1072                    let v: &V = value.borrow();
1073                    predicate(v)
1074                })
1075                .unwrap_or(false)
1076        }
1077    }
1078
1079    /// Check if all elements satisfy a predicate (for collection values)
1080    ///
1081    /// # Example
1082    /// ```
1083    /// use rust_key_paths::{Kp, KpType};
1084    /// struct User { scores: Vec<i32> }
1085    /// let user = User { scores: vec![85, 92, 78] };
1086    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1087    /// let all_passing = scores_kp.all(|scores| scores.iter().all(|&s| s >= 70));
1088    /// assert!(all_passing(&user));
1089    /// ```
1090    pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
1091    where
1092        // No Copy needed - predicate is only captured once by the returned closure
1093        // 'static: Required so the returned function can outlive the call
1094        F: Fn(&V) -> bool + 'static,
1095        V: 'static,
1096    {
1097        move |root: Root| {
1098            (&self.get)(root)
1099                .map(|value| {
1100                    let v: &V = value.borrow();
1101                    predicate(v)
1102                })
1103                .unwrap_or(true)
1104        }
1105    }
1106
1107    /// Count elements in a collection value
1108    ///
1109    /// # Example
1110    /// ```
1111    /// use rust_key_paths::{Kp, KpType};
1112    /// struct User { tags: Vec<&'static str> }
1113    /// let user = User { tags: vec!["rust", "web", "backend"] };
1114    /// let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
1115    /// let count = tags_kp.count_items(|tags| tags.len());
1116    /// assert_eq!(count(&user), Some(3));
1117    /// ```
1118    pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
1119    where
1120        // No Copy needed - counter is only captured once by the returned closure
1121        // 'static: Required so the returned function can outlive the call
1122        F: Fn(&V) -> usize + 'static,
1123        V: 'static,
1124    {
1125        move |root: Root| {
1126            (&self.get)(root).map(|value| {
1127                let v: &V = value.borrow();
1128                counter(v)
1129            })
1130        }
1131    }
1132
1133    /// Find first element matching predicate in a collection value
1134    ///
1135    /// # Example
1136    /// ```
1137    /// use rust_key_paths::{Kp, KpType};
1138    /// struct User { scores: Vec<i32> }
1139    /// let user = User { scores: vec![85, 92, 78, 95] };
1140    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1141    /// let first_high = scores_kp.find_in(|scores| {
1142    ///     scores.iter().find(|&&s| s > 90).copied()
1143    /// });
1144    /// assert_eq!(first_high(&user), Some(92));
1145    /// ```
1146    pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
1147    where
1148        // No Copy needed - finder is only captured once by the returned closure
1149        // 'static: Required so the returned function can outlive the call
1150        F: Fn(&V) -> Option<Item> + 'static,
1151        V: 'static,
1152        Item: 'static,
1153    {
1154        move |root: Root| {
1155            (&self.get)(root).and_then(|value| {
1156                let v: &V = value.borrow();
1157                finder(v)
1158            })
1159        }
1160    }
1161
1162    /// Take first N elements from a collection value
1163    ///
1164    /// # Example
1165    /// ```
1166    /// use rust_key_paths::{Kp, KpType};
1167    /// struct User { tags: Vec<&'static str> }
1168    /// let user = User { tags: vec!["a", "b", "c", "d"] };
1169    /// let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
1170    /// let first_two = tags_kp.take(2, |tags, n| tags.iter().take(n).cloned().collect::<Vec<_>>());
1171    /// ```
1172    pub fn take<Output, F>(&self, n: usize, taker: F) -> impl Fn(Root) -> Option<Output>
1173    where
1174        // No Copy needed - taker is only captured once by the returned closure
1175        // 'static: Required so the returned function can outlive the call
1176        F: Fn(&V, usize) -> Output + 'static,
1177        V: 'static,
1178        Output: 'static,
1179    {
1180        move |root: Root| {
1181            (&self.get)(root).map(|value| {
1182                let v: &V = value.borrow();
1183                taker(v, n)
1184            })
1185        }
1186    }
1187
1188    /// Skip first N elements from a collection value
1189    ///
1190    /// # Example
1191    /// ```
1192    /// use rust_key_paths::{Kp, KpType};
1193    /// struct User { tags: Vec<&'static str> }
1194    /// let user = User { tags: vec!["a", "b", "c", "d"] };
1195    /// let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
1196    /// let after_two = tags_kp.skip(2, |tags, n| tags.iter().skip(n).cloned().collect::<Vec<_>>());
1197    /// ```
1198    pub fn skip<Output, F>(&self, n: usize, skipper: F) -> impl Fn(Root) -> Option<Output>
1199    where
1200        // No Copy needed - skipper is only captured once by the returned closure
1201        // 'static: Required so the returned function can outlive the call
1202        F: Fn(&V, usize) -> Output + 'static,
1203        V: 'static,
1204        Output: 'static,
1205    {
1206        move |root: Root| {
1207            (&self.get)(root).map(|value| {
1208                let v: &V = value.borrow();
1209                skipper(v, n)
1210            })
1211        }
1212    }
1213
1214    /// Partition a collection value into two groups based on predicate
1215    ///
1216    /// # Example
1217    /// ```
1218    /// use rust_key_paths::{Kp, KpType};
1219    /// struct User { scores: Vec<i32> }
1220    /// let user = User { scores: vec![85, 92, 65, 95, 72] };
1221    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1222    /// let (passing, failing): (Vec<i32>, Vec<i32>) = scores_kp.partition_value(|scores| {
1223    ///     scores.iter().copied().partition(|&s| s >= 70)
1224    /// })(&user).unwrap();
1225    /// ```
1226    pub fn partition_value<Output, F>(&self, partitioner: F) -> impl Fn(Root) -> Option<Output>
1227    where
1228        // No Copy needed - partitioner is only captured once by the returned closure
1229        // 'static: Required so the returned function can outlive the call
1230        F: Fn(&V) -> Output + 'static,
1231        V: 'static,
1232        Output: 'static,
1233    {
1234        move |root: Root| {
1235            (&self.get)(root).map(|value| {
1236                let v: &V = value.borrow();
1237                partitioner(v)
1238            })
1239        }
1240    }
1241
1242    /// Get min value from a collection
1243    ///
1244    /// # Example
1245    /// ```
1246    /// use rust_key_paths::{Kp, KpType};
1247    /// struct User { scores: Vec<i32> }
1248    /// let user = User { scores: vec![85, 92, 78] };
1249    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1250    /// let min = scores_kp.min_value(|scores| scores.iter().min().copied());
1251    /// assert_eq!(min(&user), Some(78));
1252    /// ```
1253    pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
1254    where
1255        // No Copy needed - min_fn is only captured once by the returned closure
1256        // 'static: Required so the returned function can outlive the call
1257        F: Fn(&V) -> Option<Item> + 'static,
1258        V: 'static,
1259        Item: 'static,
1260    {
1261        move |root: Root| {
1262            (&self.get)(root).and_then(|value| {
1263                let v: &V = value.borrow();
1264                min_fn(v)
1265            })
1266        }
1267    }
1268
1269    /// Get max value from a collection
1270    ///
1271    /// # Example
1272    /// ```
1273    /// use rust_key_paths::{Kp, KpType};
1274    /// struct User { scores: Vec<i32> }
1275    /// let user = User { scores: vec![85, 92, 78] };
1276    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1277    /// let max = scores_kp.max_value(|scores| scores.iter().max().copied());
1278    /// assert_eq!(max(&user), Some(92));
1279    /// ```
1280    pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
1281    where
1282        // No Copy needed - max_fn is only captured once by the returned closure
1283        // 'static: Required so the returned function can outlive the call
1284        F: Fn(&V) -> Option<Item> + 'static,
1285        V: 'static,
1286        Item: 'static,
1287    {
1288        move |root: Root| {
1289            (&self.get)(root).and_then(|value| {
1290                let v: &V = value.borrow();
1291                max_fn(v)
1292            })
1293        }
1294    }
1295
1296    /// Sum numeric values in a collection
1297    ///
1298    /// # Example
1299    /// ```
1300    /// use rust_key_paths::{Kp, KpType};
1301    /// struct User { scores: Vec<i32> }
1302    /// let user = User { scores: vec![85, 92, 78] };
1303    /// let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
1304    /// let sum = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum());
1305    /// assert_eq!(sum(&user), Some(255));
1306    /// ```
1307    pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
1308    where
1309        // No Copy needed - sum_fn is only captured once by the returned closure
1310        // 'static: Required so the returned function can outlive the call
1311        F: Fn(&V) -> Sum + 'static,
1312        V: 'static,
1313        Sum: 'static,
1314    {
1315        move |root: Root| {
1316            (&self.get)(root).map(|value| {
1317                let v: &V = value.borrow();
1318                sum_fn(v)
1319            })
1320        }
1321    }
1322
1323    /// Chain this keypath with another to create a composition
1324    /// Alias for `then` with a more descriptive name
1325    pub fn chain<SV, SubValue, MutSubValue, G2, S2>(
1326        self,
1327        next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>,
1328    ) -> Kp<
1329        R,
1330        SV,
1331        Root,
1332        SubValue,
1333        MutRoot,
1334        MutSubValue,
1335        impl Fn(Root) -> Option<SubValue>,
1336        impl Fn(MutRoot) -> Option<MutSubValue>,
1337    >
1338    where
1339        SubValue: std::borrow::Borrow<SV>,
1340        MutSubValue: std::borrow::BorrowMut<SV>,
1341        G2: Fn(Value) -> Option<SubValue>,
1342        S2: Fn(MutValue) -> Option<MutSubValue>,
1343        V: 'static,
1344    {
1345        self.then(next)
1346    }
1347
1348    pub fn for_arc<'b>(
1349        &self,
1350    ) -> Kp<
1351        std::sync::Arc<R>,
1352        V,
1353        std::sync::Arc<R>,
1354        Value,
1355        std::sync::Arc<R>,
1356        MutValue,
1357        impl Fn(std::sync::Arc<R>) -> Option<Value>,
1358        impl Fn(std::sync::Arc<R>) -> Option<MutValue>,
1359    >
1360    where
1361        R: 'b,
1362        V: 'b,
1363        Root: for<'a> From<&'a R>,
1364        MutRoot: for<'a> From<&'a mut R>,
1365    {
1366        Kp::new(
1367            move |arc_root: std::sync::Arc<R>| {
1368                let r_ref: &R = &*arc_root;
1369                (&self.get)(Root::from(r_ref))
1370            },
1371            move |mut arc_root: std::sync::Arc<R>| {
1372                // Get mutable reference only if we have exclusive ownership
1373                std::sync::Arc::get_mut(&mut arc_root)
1374                    .and_then(|r_mut| (&self.set)(MutRoot::from(r_mut)))
1375            },
1376        )
1377    }
1378
1379    pub fn for_box<'a>(
1380        &self,
1381    ) -> Kp<
1382        Box<R>,
1383        V,
1384        Box<R>,
1385        Value,
1386        Box<R>,
1387        MutValue,
1388        impl Fn(Box<R>) -> Option<Value>,
1389        impl Fn(Box<R>) -> Option<MutValue>,
1390    >
1391    where
1392        R: 'a,
1393        V: 'a,
1394        Root: for<'b> From<&'b R>,
1395        MutRoot: for<'b> From<&'b mut R>,
1396    {
1397        Kp::new(
1398            move |r: Box<R>| {
1399                let r_ref: &R = r.as_ref();
1400                (&self.get)(Root::from(r_ref))
1401            },
1402            move |mut r: Box<R>| {
1403                // Get mutable reference only if we have exclusive ownership
1404                (self.set)(MutRoot::from(r.as_mut()))
1405            },
1406        )
1407    }
1408}
1409
1410/// Zip two keypaths together to create a tuple
1411/// Works only with KpType (reference-based keypaths)
1412///
1413/// # Example
1414/// ```
1415/// use rust_key_paths::{KpType, zip_kps};
1416/// struct User { name: String, age: i32 }
1417/// let user = User { name: "Alice".to_string(), age: 30 };
1418/// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
1419/// let age_kp = KpType::new(|u: &User| Some(&u.age), |_| None);
1420/// let zipped_fn = zip_kps(&name_kp, &age_kp);
1421/// assert_eq!(zipped_fn(&user), Some((&"Alice".to_string(), &30)));
1422/// ```
1423pub fn zip_kps<'a, RootType, Value1, Value2>(
1424    kp1: &'a KpType<'a, RootType, Value1>,
1425    kp2: &'a KpType<'a, RootType, Value2>,
1426) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1427where
1428    RootType: 'a,
1429    Value1: 'a,
1430    Value2: 'a,
1431{
1432    move |root: &'a RootType| {
1433        let val1 = (kp1.get)(root)?;
1434        let val2 = (kp2.get)(root)?;
1435        Some((val1, val2))
1436    }
1437}
1438
1439impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1440where
1441    Root: std::borrow::Borrow<R>,
1442    MutRoot: std::borrow::BorrowMut<R>,
1443    G: Fn(Root) -> Option<Root>,
1444    S: Fn(MutRoot) -> Option<MutRoot>,
1445{
1446    pub fn identity_typed() -> Kp<
1447        R,
1448        R,
1449        Root,
1450        Root,
1451        MutRoot,
1452        MutRoot,
1453        fn(Root) -> Option<Root>,
1454        fn(MutRoot) -> Option<MutRoot>,
1455    > {
1456        Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1457    }
1458
1459    pub fn identity<'a>() -> KpType<'a, R, R> {
1460        KpType::new(|r| Some(r), |r| Some(r))
1461    }
1462}
1463
1464// ========== ENUM KEYPATHS ==========
1465
1466/// EnumKp - A keypath for enum variants that supports both extraction and embedding
1467/// Leverages the existing Kp architecture where optionals are built-in via Option<Value>
1468///
1469/// This struct serves dual purposes:
1470/// 1. As a concrete keypath instance for extracting and embedding enum variants
1471/// 2. As a namespace for static factory methods: `EnumKp::for_ok()`, `EnumKp::for_some()`, etc.
1472pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1473where
1474    Root: std::borrow::Borrow<Enum>,
1475    Value: std::borrow::Borrow<Variant>,
1476    MutRoot: std::borrow::BorrowMut<Enum>,
1477    MutValue: std::borrow::BorrowMut<Variant>,
1478    G: Fn(Root) -> Option<Value>,
1479    S: Fn(MutRoot) -> Option<MutValue>,
1480    E: Fn(Variant) -> Enum,
1481{
1482    extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1483    embedder: E,
1484}
1485
1486impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1487    EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1488where
1489    Root: std::borrow::Borrow<Enum>,
1490    Value: std::borrow::Borrow<Variant>,
1491    MutRoot: std::borrow::BorrowMut<Enum>,
1492    MutValue: std::borrow::BorrowMut<Variant>,
1493    G: Fn(Root) -> Option<Value>,
1494    S: Fn(MutRoot) -> Option<MutValue>,
1495    E: Fn(Variant) -> Enum,
1496{
1497    /// Create a new EnumKp with extractor and embedder functions
1498    pub fn new(
1499        extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1500        embedder: E,
1501    ) -> Self {
1502        Self {
1503            extractor,
1504            embedder,
1505        }
1506    }
1507
1508    /// Extract the variant from an enum (returns None if wrong variant)
1509    pub fn get(&self, enum_value: Root) -> Option<Value> {
1510        self.extractor.get(enum_value)
1511    }
1512
1513    /// Extract the variant mutably from an enum (returns None if wrong variant)
1514    pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1515        self.extractor.get_mut(enum_value)
1516    }
1517
1518    /// Embed a value into the enum variant
1519    pub fn embed(&self, value: Variant) -> Enum {
1520        (self.embedder)(value)
1521    }
1522
1523    /// Get the underlying Kp for composition with other keypaths
1524    pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1525        &self.extractor
1526    }
1527
1528    /// Convert to Kp (loses embedding capability but gains composition)
1529    pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1530        self.extractor
1531    }
1532
1533    /// Map the variant value through a transformation function
1534    ///
1535    /// # Example
1536    /// ```
1537    /// use rust_key_paths::enum_ok;
1538    /// let result: Result<String, i32> = Ok("hello".to_string());
1539    /// let ok_kp = enum_ok();
1540    /// let len_kp = ok_kp.map(|s: &String| s.len());
1541    /// assert_eq!(len_kp.get(&result), Some(5));
1542    /// ```
1543    pub fn map<MappedValue, F>(
1544        &self,
1545        mapper: F,
1546    ) -> EnumKp<
1547        Enum,
1548        MappedValue,
1549        Root,
1550        MappedValue,
1551        MutRoot,
1552        MappedValue,
1553        impl Fn(Root) -> Option<MappedValue>,
1554        impl Fn(MutRoot) -> Option<MappedValue>,
1555        impl Fn(MappedValue) -> Enum,
1556    >
1557    where
1558        // Copy: Required because mapper is used via extractor.map() which needs it
1559        // 'static: Required because the returned EnumKp must own its closures
1560        F: Fn(&Variant) -> MappedValue + Copy + 'static,
1561        Variant: 'static,
1562        MappedValue: 'static,
1563        // Copy: Required for embedder to be captured in the panic closure
1564        E: Fn(Variant) -> Enum + Copy + 'static,
1565    {
1566        let mapped_extractor = self.extractor.map(mapper);
1567
1568        // Create a new embedder that maps back
1569        // Note: This is a limitation - we can't reverse the map for embedding
1570        // So we create a placeholder that panics
1571        let new_embedder = move |_value: MappedValue| -> Enum {
1572            panic!(
1573                "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1574            )
1575        };
1576
1577        EnumKp::new(mapped_extractor, new_embedder)
1578    }
1579
1580    /// Filter the variant value based on a predicate
1581    /// Returns None if the predicate fails or if wrong variant
1582    ///
1583    /// # Example
1584    /// ```
1585    /// use rust_key_paths::enum_ok;
1586    /// let result: Result<i32, String> = Ok(42);
1587    /// let ok_kp = enum_ok();
1588    /// let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
1589    /// assert_eq!(positive_kp.get(&result), Some(&42));
1590    /// ```
1591    pub fn filter<F>(
1592        &self,
1593        predicate: F,
1594    ) -> EnumKp<
1595        Enum,
1596        Variant,
1597        Root,
1598        Value,
1599        MutRoot,
1600        MutValue,
1601        impl Fn(Root) -> Option<Value>,
1602        impl Fn(MutRoot) -> Option<MutValue>,
1603        E,
1604    >
1605    where
1606        // Copy: Required because predicate is used via extractor.filter() which needs it
1607        // 'static: Required because the returned EnumKp must own its closures
1608        F: Fn(&Variant) -> bool + Copy + 'static,
1609        Variant: 'static,
1610        // Copy: Required to clone embedder into the new EnumKp
1611        E: Copy,
1612    {
1613        let filtered_extractor = self.extractor.filter(predicate);
1614        EnumKp::new(filtered_extractor, self.embedder)
1615    }
1616}
1617
1618// Type alias for the common case with references
1619pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1620    Enum,
1621    Variant,
1622    &'a Enum,
1623    &'a Variant,
1624    &'a mut Enum,
1625    &'a mut Variant,
1626    for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1627    for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1628    fn(Variant) -> Enum,
1629>;
1630
1631// Static factory functions for creating EnumKp instances
1632/// Create an enum keypath with both extraction and embedding for a specific variant
1633///
1634/// # Example
1635/// ```
1636/// use rust_key_paths::enum_variant;
1637/// enum MyEnum {
1638///     A(String),
1639///     B(i32),
1640/// }
1641///
1642/// let kp = enum_variant(
1643///     |e: &MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1644///     |e: &mut MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1645///     |s: String| MyEnum::A(s)
1646/// );
1647/// ```
1648pub fn enum_variant<'a, Enum, Variant>(
1649    getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1650    setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1651    embedder: fn(Variant) -> Enum,
1652) -> EnumKpType<'a, Enum, Variant> {
1653    EnumKp::new(Kp::new(getter, setter), embedder)
1654}
1655
1656/// Extract from Result<T, E> - Ok variant
1657///
1658/// # Example
1659/// ```
1660/// use rust_key_paths::enum_ok;
1661/// let result: Result<String, i32> = Ok("success".to_string());
1662/// let ok_kp = enum_ok();
1663/// assert_eq!(ok_kp.get(&result), Some(&"success".to_string()));
1664/// ```
1665pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1666    EnumKp::new(
1667        Kp::new(
1668            |r: &Result<T, E>| r.as_ref().ok(),
1669            |r: &mut Result<T, E>| r.as_mut().ok(),
1670        ),
1671        |t: T| Ok(t),
1672    )
1673}
1674
1675/// Extract from Result<T, E> - Err variant
1676///
1677/// # Example
1678/// ```
1679/// use rust_key_paths::enum_err;
1680/// let result: Result<String, i32> = Err(42);
1681/// let err_kp = enum_err();
1682/// assert_eq!(err_kp.get(&result), Some(&42));
1683/// ```
1684pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1685    EnumKp::new(
1686        Kp::new(
1687            |r: &Result<T, E>| r.as_ref().err(),
1688            |r: &mut Result<T, E>| r.as_mut().err(),
1689        ),
1690        |e: E| Err(e),
1691    )
1692}
1693
1694/// Extract from Option<T> - Some variant
1695///
1696/// # Example
1697/// ```
1698/// use rust_key_paths::enum_some;
1699/// let opt = Some("value".to_string());
1700/// let some_kp = enum_some();
1701/// assert_eq!(some_kp.get(&opt), Some(&"value".to_string()));
1702/// ```
1703pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1704    EnumKp::new(
1705        Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1706        |t: T| Some(t),
1707    )
1708}
1709
1710// Helper functions for creating enum keypaths with type inference
1711/// Create an enum keypath for a specific variant with type inference
1712///
1713/// # Example
1714/// ```
1715/// use rust_key_paths::variant_of;
1716/// enum MyEnum {
1717///     A(String),
1718///     B(i32),
1719/// }
1720///
1721/// let kp_a = variant_of(
1722///     |e: &MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1723///     |e: &mut MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1724///     |s: String| MyEnum::A(s)
1725/// );
1726/// ```
1727pub fn variant_of<'a, Enum, Variant>(
1728    getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1729    setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1730    embedder: fn(Variant) -> Enum,
1731) -> EnumKpType<'a, Enum, Variant> {
1732    enum_variant(getter, setter, embedder)
1733}
1734
1735// ========== CONTAINER KEYPATHS ==========
1736
1737// Helper functions for working with standard containers (Box, Arc, Rc)
1738/// Create a keypath for unwrapping Box<T> -> T
1739///
1740/// # Example
1741/// ```
1742/// use rust_key_paths::kp_box;
1743/// let boxed = Box::new("value".to_string());
1744/// let kp = kp_box();
1745/// assert_eq!(kp.get(&boxed), Some(&"value".to_string()));
1746/// ```
1747pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1748    Kp::new(
1749        |b: &Box<T>| Some(b.as_ref()),
1750        |b: &mut Box<T>| Some(b.as_mut()),
1751    )
1752}
1753
1754/// Create a keypath for unwrapping Arc<T> -> T (read-only)
1755///
1756/// # Example
1757/// ```
1758/// use std::sync::Arc;
1759/// use rust_key_paths::kp_arc;
1760/// let arc = Arc::new("value".to_string());
1761/// let kp = kp_arc();
1762/// assert_eq!(kp.get(&arc), Some(&"value".to_string()));
1763/// ```
1764pub fn kp_arc<'a, T>() -> Kp<
1765    Arc<T>,
1766    T,
1767    &'a Arc<T>,
1768    &'a T,
1769    &'a mut Arc<T>,
1770    &'a mut T,
1771    for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1772    for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1773> {
1774    Kp::new(
1775        |arc: &Arc<T>| Some(arc.as_ref()),
1776        |arc: &mut Arc<T>| Arc::get_mut(arc),
1777    )
1778}
1779
1780/// Create a keypath for unwrapping Rc<T> -> T (read-only)
1781///
1782/// # Example
1783/// ```
1784/// use std::rc::Rc;
1785/// use rust_key_paths::kp_rc;
1786/// let rc = Rc::new("value".to_string());
1787/// let kp = kp_rc();
1788/// assert_eq!(kp.get(&rc), Some(&"value".to_string()));
1789/// ```
1790pub fn kp_rc<'a, T>() -> Kp<
1791    std::rc::Rc<T>,
1792    T,
1793    &'a std::rc::Rc<T>,
1794    &'a T,
1795    &'a mut std::rc::Rc<T>,
1796    &'a mut T,
1797    for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1798    for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1799> {
1800    Kp::new(
1801        |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1802        |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1803    )
1804}
1805
1806// ========== PARTIAL KEYPATHS (Hide Value Type) ==========
1807
1808use std::any::{Any, TypeId};
1809use std::rc::Rc;
1810
1811/// PKp (PartialKeyPath) - Hides the Value type but keeps Root visible
1812/// Useful for storing keypaths in collections without knowing the exact Value type
1813///
1814/// # Why PhantomData<Root>?
1815///
1816/// `PhantomData<Root>` is needed because:
1817/// 1. The `Root` type parameter is not actually stored in the struct (only used in the closure)
1818/// 2. Rust needs to know the generic type parameter for:
1819///    - Type checking at compile time
1820///    - Ensuring correct usage (e.g., `PKp<User>` can only be used with `&User`)
1821///    - Preventing mixing different Root types
1822/// 3. Without `PhantomData`, Rust would complain that `Root` is unused
1823/// 4. `PhantomData` is zero-sized - it adds no runtime overhead
1824
1825#[cfg(test)]
1826mod tests {
1827    use super::*;
1828    use std::collections::HashMap;
1829
1830    #[derive(Debug)]
1831    struct TestKP {
1832        a: String,
1833        b: String,
1834        c: std::sync::Arc<String>,
1835        d: std::sync::Mutex<String>,
1836        e: std::sync::Arc<std::sync::Mutex<TestKP2>>,
1837        f: Option<TestKP2>,
1838        g: HashMap<i32, TestKP2>,
1839    }
1840
1841    impl TestKP {
1842        fn new() -> Self {
1843            Self {
1844                a: String::from("a"),
1845                b: String::from("b"),
1846                c: std::sync::Arc::new(String::from("c")),
1847                d: std::sync::Mutex::new(String::from("d")),
1848                e: std::sync::Arc::new(std::sync::Mutex::new(TestKP2::new())),
1849                f: Some(TestKP2 {
1850                    a: String::from("a3"),
1851                    b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1852                }),
1853                g: HashMap::new(),
1854            }
1855        }
1856
1857        fn g(index: i32) -> KpComposed<TestKP, TestKP2> {
1858            KpComposed::from_closures(
1859                move |r: &TestKP| r.g.get(&index),
1860                move |r: &mut TestKP| r.g.get_mut(&index),
1861            )
1862        }
1863
1864        // Example for - Clone ref sharing
1865        // Keypath for field 'a' (String)
1866        fn a_typed<Root, MutRoot, Value, MutValue>() -> Kp<
1867            TestKP2,
1868            String,
1869            Root,
1870            Value,
1871            MutRoot,
1872            MutValue,
1873            impl Fn(Root) -> Option<Value>,
1874            impl Fn(MutRoot) -> Option<MutValue>,
1875        >
1876        where
1877            Root: std::borrow::Borrow<TestKP2>,
1878            MutRoot: std::borrow::BorrowMut<TestKP2>,
1879            Value: std::borrow::Borrow<String> + From<String>,
1880            MutValue: std::borrow::BorrowMut<String> + From<String>,
1881        {
1882            Kp::new(
1883                |r: Root| Some(Value::from(r.borrow().a.clone())),
1884                |mut r: MutRoot| Some(MutValue::from(r.borrow_mut().a.clone())),
1885            )
1886        }
1887
1888        // Example for taking ref
1889
1890        fn c<'a>() -> KpType<'a, TestKP, String> {
1891            KpType::new(
1892                |r: &TestKP| Some(r.c.as_ref()),
1893                |r: &mut TestKP| match std::sync::Arc::get_mut(&mut r.c) {
1894                    Some(arc_str) => Some(arc_str),
1895                    None => None,
1896                },
1897            )
1898        }
1899
1900        fn a<'a>() -> KpType<'a, TestKP, String> {
1901            KpType::new(|r: &TestKP| Some(&r.a), |r: &mut TestKP| Some(&mut r.a))
1902        }
1903
1904        fn f<'a>() -> KpType<'a, TestKP, TestKP2> {
1905            KpType::new(|r: &TestKP| r.f.as_ref(), |r: &mut TestKP| r.f.as_mut())
1906        }
1907
1908        fn identity<'a>() -> KpType<'a, TestKP, TestKP> {
1909            KpType::identity()
1910        }
1911    }
1912
1913    #[derive(Debug)]
1914    struct TestKP2 {
1915        a: String,
1916        b: std::sync::Arc<std::sync::Mutex<TestKP3>>,
1917    }
1918
1919    impl TestKP2 {
1920        fn new() -> Self {
1921            TestKP2 {
1922                a: String::from("a2"),
1923                b: std::sync::Arc::new(std::sync::Mutex::new(TestKP3::new())),
1924            }
1925        }
1926
1927        fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1928            TestKP2, // R
1929            TestKP2, // V
1930            Root,    // Root
1931            Root,    // Value
1932            MutRoot, // MutRoot
1933            MutRoot, // MutValue
1934            fn(Root) -> Option<Root>,
1935            fn(MutRoot) -> Option<MutRoot>,
1936        >
1937        where
1938            Root: std::borrow::Borrow<TestKP2>,
1939            MutRoot: std::borrow::BorrowMut<TestKP2>,
1940            G: Fn(Root) -> Option<Root>,
1941            S: Fn(MutRoot) -> Option<MutRoot>,
1942        {
1943            Kp::<TestKP2, TestKP2, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1944        }
1945
1946        fn a<'a>() -> KpType<'a, TestKP2, String> {
1947            KpType::new(|r: &TestKP2| Some(&r.a), |r: &mut TestKP2| Some(&mut r.a))
1948        }
1949
1950        fn b<'a>() -> KpType<'a, TestKP2, std::sync::Arc<std::sync::Mutex<TestKP3>>> {
1951            KpType::new(|r: &TestKP2| Some(&r.b), |r: &mut TestKP2| Some(&mut r.b))
1952        }
1953
1954        // fn b_lock<'a, V>(kp: KpType<'a, TestKP2, V>) -> KpType<'a, TestKP2, std::sync::MutexGuard<'a, TestKP3>> {
1955        //     KpType::new(|r: &TestKP2| Some(r.b.lock().unwrap()), |r: &mut TestKP2| Some(r.b.lock().unwrap()))
1956        // }
1957
1958        fn identity<'a>() -> KpType<'a, TestKP2, TestKP2> {
1959            KpType::identity()
1960        }
1961    }
1962
1963    #[derive(Debug)]
1964    struct TestKP3 {
1965        a: String,
1966        b: std::sync::Arc<std::sync::Mutex<String>>,
1967    }
1968
1969    impl TestKP3 {
1970        fn new() -> Self {
1971            TestKP3 {
1972                a: String::from("a2"),
1973                b: std::sync::Arc::new(std::sync::Mutex::new(String::from("b2"))),
1974            }
1975        }
1976
1977        fn identity_typed<Root, MutRoot, G, S>() -> Kp<
1978            TestKP3, // R
1979            TestKP3, // V
1980            Root,    // Root
1981            Root,    // Value
1982            MutRoot, // MutRoot
1983            MutRoot, // MutValue
1984            fn(Root) -> Option<Root>,
1985            fn(MutRoot) -> Option<MutRoot>,
1986        >
1987        where
1988            Root: std::borrow::Borrow<TestKP3>,
1989            MutRoot: std::borrow::BorrowMut<TestKP3>,
1990            G: Fn(Root) -> Option<Root>,
1991            S: Fn(MutRoot) -> Option<MutRoot>,
1992        {
1993            Kp::<TestKP3, TestKP3, Root, Root, MutRoot, MutRoot, G, S>::identity_typed()
1994        }
1995
1996        fn identity<'a>() -> KpType<'a, TestKP3, TestKP3> {
1997            KpType::identity()
1998        }
1999    }
2000
2001    impl TestKP3 {}
2002
2003    impl TestKP {}
2004    #[test]
2005    fn test_a() {
2006        let instance2 = TestKP2::new();
2007        let mut instance = TestKP::new();
2008        let kp = TestKP::identity();
2009        let kp_a = TestKP::a();
2010        // TestKP::a().for_arc();
2011        let wres = TestKP::f().then(TestKP2::a()).get_mut(&mut instance).unwrap();
2012        *wres = String::from("a3 changed successfully");
2013        let res = TestKP::f().then(TestKP2::a()).get(&instance);
2014        println!("{:?}", res);
2015        let res = TestKP::f().then(TestKP2::identity()).get(&instance);
2016        println!("{:?}", res);
2017        let res = kp.get(&instance);
2018        println!("{:?}", res);
2019
2020        let new_kp_from_hashmap = TestKP::g(0).then(TestKP2::a());
2021        println!("{:?}", new_kp_from_hashmap.get(&instance));
2022    }
2023
2024    // #[test]
2025    // fn test_lock() {
2026    //     let lock_kp = LockKp::new(A::b(), kp_arc_mutex::<B>(), B::c());
2027    //
2028    //     let mut a = A {
2029    //         b: Arc::new(Mutex::new(B {
2030    //             c: C {
2031    //                 d: String::from("hello"),
2032    //             },
2033    //         })),
2034    //     };
2035    //
2036    //     // Get value
2037    //     if let Some(value) = lock_kp.get(&a) {
2038    //         println!("Got: {:?}", value);
2039    //         assert_eq!(value.d, "hello");
2040    //     } else {
2041    //         panic!("Value not found");
2042    //     }
2043    //
2044    //     // Set value using closure
2045    //     let result = lock_kp.set(&a, |d| {
2046    //         d.d.push_str(" world");
2047    //     });
2048    //
2049    //     if result.is_ok() {
2050    //         if let Some(value) = lock_kp.get(&a) {
2051    //             println!("After set: {:?}", value);
2052    //             assert_eq!(value.d, "hello");
2053    //         } else {
2054    //             panic!("Value not found");
2055    //         }
2056    //     }
2057    // }
2058
2059    #[test]
2060    fn test_enum_kp_result_ok() {
2061        let ok_result: Result<String, i32> = Ok("success".to_string());
2062        let mut err_result: Result<String, i32> = Err(42);
2063
2064        let ok_kp = enum_ok();
2065
2066        // Test extraction
2067        assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2068        assert_eq!(ok_kp.get(&err_result), None);
2069
2070        // Test embedding
2071        let embedded = ok_kp.embed("embedded".to_string());
2072        assert_eq!(embedded, Ok("embedded".to_string()));
2073
2074        // Test mutable access
2075        if let Some(val) = ok_kp.get_mut(&mut err_result) {
2076            *val = "modified".to_string();
2077        }
2078        assert_eq!(err_result, Err(42)); // Should still be Err
2079
2080        let mut ok_result2 = Ok("original".to_string());
2081        if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2082            *val = "modified".to_string();
2083        }
2084        assert_eq!(ok_result2, Ok("modified".to_string()));
2085    }
2086
2087    #[test]
2088    fn test_enum_kp_result_err() {
2089        let ok_result: Result<String, i32> = Ok("success".to_string());
2090        let mut err_result: Result<String, i32> = Err(42);
2091
2092        let err_kp = enum_err();
2093
2094        // Test extraction
2095        assert_eq!(err_kp.get(&err_result), Some(&42));
2096        assert_eq!(err_kp.get(&ok_result), None);
2097
2098        // Test embedding
2099        let embedded = err_kp.embed(99);
2100        assert_eq!(embedded, Err(99));
2101
2102        // Test mutable access
2103        if let Some(val) = err_kp.get_mut(&mut err_result) {
2104            *val = 100;
2105        }
2106        assert_eq!(err_result, Err(100));
2107    }
2108
2109    #[test]
2110    fn test_enum_kp_option_some() {
2111        let some_opt = Some("value".to_string());
2112        let mut none_opt: Option<String> = None;
2113
2114        let some_kp = enum_some();
2115
2116        // Test extraction
2117        assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2118        assert_eq!(some_kp.get(&none_opt), None);
2119
2120        // Test embedding
2121        let embedded = some_kp.embed("embedded".to_string());
2122        assert_eq!(embedded, Some("embedded".to_string()));
2123
2124        // Test mutable access
2125        let mut some_opt2 = Some("original".to_string());
2126        if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2127            *val = "modified".to_string();
2128        }
2129        assert_eq!(some_opt2, Some("modified".to_string()));
2130    }
2131
2132    #[test]
2133    fn test_enum_kp_custom_enum() {
2134        #[derive(Debug, PartialEq)]
2135        enum MyEnum {
2136            A(String),
2137            B(i32),
2138            C,
2139        }
2140
2141        let mut enum_a = MyEnum::A("hello".to_string());
2142        let enum_b = MyEnum::B(42);
2143        let enum_c = MyEnum::C;
2144
2145        // Create keypath for variant A
2146        let kp_a = enum_variant(
2147            |e: &MyEnum| match e {
2148                MyEnum::A(s) => Some(s),
2149                _ => None,
2150            },
2151            |e: &mut MyEnum| match e {
2152                MyEnum::A(s) => Some(s),
2153                _ => None,
2154            },
2155            |s: String| MyEnum::A(s),
2156        );
2157
2158        // Test extraction
2159        assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2160        assert_eq!(kp_a.get(&enum_b), None);
2161        assert_eq!(kp_a.get(&enum_c), None);
2162
2163        // Test embedding
2164        let embedded = kp_a.embed("world".to_string());
2165        assert_eq!(embedded, MyEnum::A("world".to_string()));
2166
2167        // Test mutable access
2168        if let Some(val) = kp_a.get_mut(&mut enum_a) {
2169            *val = "modified".to_string();
2170        }
2171        assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2172    }
2173
2174    #[test]
2175    fn test_container_kp_box() {
2176        let boxed = Box::new("value".to_string());
2177        let mut boxed_mut = Box::new("original".to_string());
2178
2179        let box_kp = kp_box();
2180
2181        // Test get
2182        assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2183
2184        // Test get_mut
2185        if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2186            *val = "modified".to_string();
2187        }
2188        assert_eq!(*boxed_mut, "modified".to_string());
2189    }
2190
2191    #[test]
2192    fn test_container_kp_arc() {
2193        let arc = Arc::new("value".to_string());
2194        let mut arc_mut = Arc::new("original".to_string());
2195
2196        let arc_kp = kp_arc();
2197
2198        // Test get
2199        assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2200
2201        // Test get_mut (only works if Arc has no other references)
2202        if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2203            *val = "modified".to_string();
2204        }
2205        assert_eq!(*arc_mut, "modified".to_string());
2206
2207        // Test with multiple references (should return None for mutable access)
2208        let arc_shared = Arc::new("shared".to_string());
2209        let arc_shared2 = Arc::clone(&arc_shared);
2210        let mut arc_shared_mut = arc_shared;
2211        assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2212    }
2213
2214    #[test]
2215    fn test_enum_kp_composition() {
2216        // Test composing enum keypath with other keypaths
2217        #[derive(Debug, PartialEq)]
2218        struct Inner {
2219            value: String,
2220        }
2221
2222        let result: Result<Inner, i32> = Ok(Inner {
2223            value: "nested".to_string(),
2224        });
2225
2226        // Create keypath to Inner.value
2227        let inner_kp = KpType::new(
2228            |i: &Inner| Some(&i.value),
2229            |i: &mut Inner| Some(&mut i.value),
2230        );
2231
2232        // Get the Ok keypath and convert to Kp for composition
2233        let ok_kp = enum_ok::<Inner, i32>();
2234        let ok_kp_base = ok_kp.into_kp();
2235        let composed = ok_kp_base.then(inner_kp);
2236
2237        assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2238    }
2239
2240    #[test]
2241    fn test_pkp_basic() {
2242        #[derive(Debug)]
2243        struct User {
2244            name: String,
2245            age: i32,
2246        }
2247
2248        let user = User {
2249            name: "Alice".to_string(),
2250            age: 30,
2251        };
2252
2253        // Create regular keypaths
2254        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2255        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2256
2257        // Convert to partial keypaths
2258        let name_pkp = PKp::new(name_kp);
2259        let age_pkp = PKp::new(age_kp);
2260
2261        // Test get_as with correct type
2262        assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2263        assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2264
2265        // Test get_as with wrong type returns None
2266        assert_eq!(name_pkp.get_as::<i32>(&user), None);
2267        assert_eq!(age_pkp.get_as::<String>(&user), None);
2268
2269        // Test value_type_id
2270        assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2271        assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2272    }
2273
2274    #[test]
2275    fn test_pkp_collection() {
2276        #[derive(Debug)]
2277        struct User {
2278            name: String,
2279            age: i32,
2280        }
2281
2282        let user = User {
2283            name: "Bob".to_string(),
2284            age: 25,
2285        };
2286
2287        // Create a collection of partial keypaths
2288        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2289        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2290
2291        let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2292
2293        // Access values through the collection
2294        let name_value = keypaths[0].get_as::<String>(&user);
2295        let age_value = keypaths[1].get_as::<i32>(&user);
2296
2297        assert_eq!(name_value, Some(&"Bob".to_string()));
2298        assert_eq!(age_value, Some(&25));
2299    }
2300
2301    #[test]
2302    fn test_pkp_for_arc() {
2303        #[derive(Debug)]
2304        struct User {
2305            name: String,
2306        }
2307
2308        let user = Arc::new(User {
2309            name: "Charlie".to_string(),
2310        });
2311
2312        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2313        let name_pkp = PKp::new(name_kp);
2314
2315        // Adapt for Arc
2316        let arc_pkp = name_pkp.for_arc();
2317
2318        assert_eq!(
2319            arc_pkp.get_as::<String>(&user),
2320            Some(&"Charlie".to_string())
2321        );
2322    }
2323
2324    #[test]
2325    fn test_pkp_for_option() {
2326        #[derive(Debug)]
2327        struct User {
2328            name: String,
2329        }
2330
2331        let some_user = Some(User {
2332            name: "Diana".to_string(),
2333        });
2334        let none_user: Option<User> = None;
2335
2336        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2337        let name_pkp = PKp::new(name_kp);
2338
2339        // Adapt for Option
2340        let opt_pkp = name_pkp.for_option();
2341
2342        assert_eq!(
2343            opt_pkp.get_as::<String>(&some_user),
2344            Some(&"Diana".to_string())
2345        );
2346        assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2347    }
2348
2349    #[test]
2350    fn test_akp_basic() {
2351        #[derive(Debug)]
2352        struct User {
2353            name: String,
2354            age: i32,
2355        }
2356
2357        #[derive(Debug)]
2358        struct Product {
2359            title: String,
2360            price: f64,
2361        }
2362
2363        let user = User {
2364            name: "Eve".to_string(),
2365            age: 28,
2366        };
2367
2368        let product = Product {
2369            title: "Book".to_string(),
2370            price: 19.99,
2371        };
2372
2373        // Create AnyKeypaths
2374        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2375        let user_name_akp = AKp::new(user_name_kp);
2376
2377        let product_title_kp = KpType::new(
2378            |p: &Product| Some(&p.title),
2379            |p: &mut Product| Some(&mut p.title),
2380        );
2381        let product_title_akp = AKp::new(product_title_kp);
2382
2383        // Test get_as with correct types
2384        assert_eq!(
2385            user_name_akp.get_as::<User, String>(&user),
2386            Some(Some(&"Eve".to_string()))
2387        );
2388        assert_eq!(
2389            product_title_akp.get_as::<Product, String>(&product),
2390            Some(Some(&"Book".to_string()))
2391        );
2392
2393        // Test get_as with wrong root type
2394        assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2395        assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2396
2397        // Test TypeIds
2398        assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2399        assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2400        assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2401        assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2402    }
2403
2404    #[test]
2405    fn test_akp_heterogeneous_collection() {
2406        #[derive(Debug)]
2407        struct User {
2408            name: String,
2409        }
2410
2411        #[derive(Debug)]
2412        struct Product {
2413            title: String,
2414        }
2415
2416        let user = User {
2417            name: "Frank".to_string(),
2418        };
2419        let product = Product {
2420            title: "Laptop".to_string(),
2421        };
2422
2423        // Create a heterogeneous collection of AnyKeypaths
2424        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2425        let product_title_kp = KpType::new(
2426            |p: &Product| Some(&p.title),
2427            |p: &mut Product| Some(&mut p.title),
2428        );
2429
2430        let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2431
2432        // Access through trait objects
2433        let user_any: &dyn Any = &user;
2434        let product_any: &dyn Any = &product;
2435
2436        let user_value = keypaths[0].get(user_any);
2437        let product_value = keypaths[1].get(product_any);
2438
2439        assert!(user_value.is_some());
2440        assert!(product_value.is_some());
2441
2442        // Downcast to concrete types
2443        assert_eq!(
2444            user_value.and_then(|v| v.downcast_ref::<String>()),
2445            Some(&"Frank".to_string())
2446        );
2447        assert_eq!(
2448            product_value.and_then(|v| v.downcast_ref::<String>()),
2449            Some(&"Laptop".to_string())
2450        );
2451    }
2452
2453    #[test]
2454    fn test_akp_for_option() {
2455        #[derive(Debug)]
2456        struct User {
2457            name: String,
2458        }
2459
2460        let some_user = Some(User {
2461            name: "Grace".to_string(),
2462        });
2463        let none_user: Option<User> = None;
2464
2465        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2466        let name_akp = AKp::new(name_kp);
2467
2468        // Adapt for Option
2469        let opt_akp = name_akp.for_option::<User>();
2470
2471        assert_eq!(
2472            opt_akp.get_as::<Option<User>, String>(&some_user),
2473            Some(Some(&"Grace".to_string()))
2474        );
2475        assert_eq!(
2476            opt_akp.get_as::<Option<User>, String>(&none_user),
2477            Some(None)
2478        );
2479    }
2480
2481    #[test]
2482    fn test_akp_for_result() {
2483        #[derive(Debug)]
2484        struct User {
2485            name: String,
2486        }
2487
2488        let ok_user: Result<User, String> = Ok(User {
2489            name: "Henry".to_string(),
2490        });
2491        let err_user: Result<User, String> = Err("Not found".to_string());
2492
2493        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2494        let name_akp = AKp::new(name_kp);
2495
2496        // Adapt for Result
2497        let result_akp = name_akp.for_result::<User, String>();
2498
2499        assert_eq!(
2500            result_akp.get_as::<Result<User, String>, String>(&ok_user),
2501            Some(Some(&"Henry".to_string()))
2502        );
2503        assert_eq!(
2504            result_akp.get_as::<Result<User, String>, String>(&err_user),
2505            Some(None)
2506        );
2507    }
2508
2509    // ========== MAP TESTS ==========
2510
2511    #[test]
2512    fn test_kp_map() {
2513        #[derive(Debug)]
2514        struct User {
2515            name: String,
2516            age: i32,
2517        }
2518
2519        let user = User {
2520            name: "Alice".to_string(),
2521            age: 30,
2522        };
2523
2524        // Map string to its length
2525        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2526        let len_kp = name_kp.map(|name: &String| name.len());
2527
2528        assert_eq!(len_kp.get(&user), Some(5));
2529
2530        // Map age to double
2531        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2532        let double_age_kp = age_kp.map(|age: &i32| age * 2);
2533
2534        assert_eq!(double_age_kp.get(&user), Some(60));
2535
2536        // Map to boolean
2537        let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2538        assert_eq!(is_adult_kp.get(&user), Some(true));
2539    }
2540
2541    #[test]
2542    fn test_kp_filter() {
2543        #[derive(Debug)]
2544        struct User {
2545            name: String,
2546            age: i32,
2547        }
2548
2549        let adult = User {
2550            name: "Alice".to_string(),
2551            age: 30,
2552        };
2553
2554        let minor = User {
2555            name: "Bob".to_string(),
2556            age: 15,
2557        };
2558
2559        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2560        let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2561
2562        assert_eq!(adult_age_kp.get(&adult), Some(&30));
2563        assert_eq!(adult_age_kp.get(&minor), None);
2564
2565        // Filter names by length
2566        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2567        let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2568
2569        assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2570        assert_eq!(short_name_kp.get(&adult), None);
2571    }
2572
2573    #[test]
2574    fn test_kp_map_and_filter() {
2575        #[derive(Debug)]
2576        struct User {
2577            scores: Vec<i32>,
2578        }
2579
2580        let user = User {
2581            scores: vec![85, 92, 78, 95],
2582        };
2583
2584        let scores_kp = KpType::new(
2585            |u: &User| Some(&u.scores),
2586            |u: &mut User| Some(&mut u.scores),
2587        );
2588
2589        // Map to average score
2590        let avg_kp =
2591            scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2592
2593        // Filter for high averages
2594        let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2595
2596        assert_eq!(high_avg_kp.get(&user), Some(87)); // (85+92+78+95)/4 = 87.5 -> 87
2597    }
2598
2599    #[test]
2600    fn test_enum_kp_map() {
2601        let ok_result: Result<String, i32> = Ok("hello".to_string());
2602        let err_result: Result<String, i32> = Err(42);
2603
2604        let ok_kp = enum_ok::<String, i32>();
2605        let len_kp = ok_kp.map(|s: &String| s.len());
2606
2607        assert_eq!(len_kp.get(&ok_result), Some(5));
2608        assert_eq!(len_kp.get(&err_result), None);
2609
2610        // Map Option
2611        let some_opt = Some(vec![1, 2, 3, 4, 5]);
2612        let none_opt: Option<Vec<i32>> = None;
2613
2614        let some_kp = enum_some::<Vec<i32>>();
2615        let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2616
2617        assert_eq!(count_kp.get(&some_opt), Some(5));
2618        assert_eq!(count_kp.get(&none_opt), None);
2619    }
2620
2621    #[test]
2622    fn test_enum_kp_filter() {
2623        let ok_result1: Result<i32, String> = Ok(42);
2624        let ok_result2: Result<i32, String> = Ok(-5);
2625        let err_result: Result<i32, String> = Err("error".to_string());
2626
2627        let ok_kp = enum_ok::<i32, String>();
2628        let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2629
2630        assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2631        assert_eq!(positive_kp.get(&ok_result2), None); // Negative number filtered out
2632        assert_eq!(positive_kp.get(&err_result), None); // Err variant
2633
2634        // Filter Option strings by length
2635        let long_str = Some("hello world".to_string());
2636        let short_str = Some("hi".to_string());
2637
2638        let some_kp = enum_some::<String>();
2639        let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2640
2641        assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2642        assert_eq!(long_kp.get(&short_str), None);
2643    }
2644
2645    #[test]
2646    fn test_pkp_filter() {
2647        #[derive(Debug)]
2648        struct User {
2649            name: String,
2650            age: i32,
2651        }
2652
2653        let adult = User {
2654            name: "Alice".to_string(),
2655            age: 30,
2656        };
2657
2658        let minor = User {
2659            name: "Bob".to_string(),
2660            age: 15,
2661        };
2662
2663        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2664        let age_pkp = PKp::new(age_kp);
2665
2666        // Filter for adults
2667        let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2668
2669        assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2670        assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2671
2672        // Filter names
2673        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2674        let name_pkp = PKp::new(name_kp);
2675        let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2676
2677        assert_eq!(
2678            short_name_pkp.get_as::<String>(&minor),
2679            Some(&"Bob".to_string())
2680        );
2681        assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2682    }
2683
2684    #[test]
2685    fn test_akp_filter() {
2686        #[derive(Debug)]
2687        struct User {
2688            age: i32,
2689        }
2690
2691        #[derive(Debug)]
2692        struct Product {
2693            price: f64,
2694        }
2695
2696        let adult = User { age: 30 };
2697        let minor = User { age: 15 };
2698        let expensive = Product { price: 99.99 };
2699        let cheap = Product { price: 5.0 };
2700
2701        // Filter user ages
2702        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2703        let age_akp = AKp::new(age_kp);
2704        let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2705
2706        assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2707        assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2708
2709        // Filter product prices
2710        let price_kp = KpType::new(
2711            |p: &Product| Some(&p.price),
2712            |p: &mut Product| Some(&mut p.price),
2713        );
2714        let price_akp = AKp::new(price_kp);
2715        let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2716
2717        assert_eq!(
2718            expensive_akp.get_as::<Product, f64>(&expensive),
2719            Some(Some(&99.99))
2720        );
2721        assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2722    }
2723
2724    // ========== ITERATOR-RELATED HOF TESTS ==========
2725
2726    #[test]
2727    fn test_kp_filter_map() {
2728        #[derive(Debug)]
2729        struct User {
2730            middle_name: Option<String>,
2731        }
2732
2733        let user_with = User {
2734            middle_name: Some("Marie".to_string()),
2735        };
2736        let user_without = User { middle_name: None };
2737
2738        let middle_kp = KpType::new(
2739            |u: &User| Some(&u.middle_name),
2740            |u: &mut User| Some(&mut u.middle_name),
2741        );
2742
2743        let first_char_kp = middle_kp
2744            .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2745
2746        assert_eq!(first_char_kp.get(&user_with), Some('M'));
2747        assert_eq!(first_char_kp.get(&user_without), None);
2748    }
2749
2750    #[test]
2751    fn test_kp_inspect() {
2752        #[derive(Debug)]
2753        struct User {
2754            name: String,
2755        }
2756
2757        let user = User {
2758            name: "Alice".to_string(),
2759        };
2760
2761        // Simple test - just verify that inspect returns the correct value
2762        // and can perform side effects
2763
2764        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2765
2766        // We can't easily test side effects with Copy constraint,
2767        // so we'll just test that inspect passes through the value
2768        let result = name_kp.get(&user);
2769        assert_eq!(result, Some(&"Alice".to_string()));
2770
2771        // The inspect method works, it just requires Copy closures
2772        // which limits its usefulness for complex side effects
2773    }
2774
2775    #[test]
2776    fn test_kp_fold_value() {
2777        #[derive(Debug)]
2778        struct User {
2779            scores: Vec<i32>,
2780        }
2781
2782        let user = User {
2783            scores: vec![85, 92, 78, 95],
2784        };
2785
2786        let scores_kp = KpType::new(
2787            |u: &User| Some(&u.scores),
2788            |u: &mut User| Some(&mut u.scores),
2789        );
2790
2791        // Sum all scores
2792        let sum_fn =
2793            scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2794
2795        assert_eq!(sum_fn(&user), 350);
2796    }
2797
2798    #[test]
2799    fn test_kp_any_all() {
2800        #[derive(Debug)]
2801        struct User {
2802            scores: Vec<i32>,
2803        }
2804
2805        let user_high = User {
2806            scores: vec![85, 92, 88],
2807        };
2808        let user_mixed = User {
2809            scores: vec![65, 92, 78],
2810        };
2811
2812        let scores_kp = KpType::new(
2813            |u: &User| Some(&u.scores),
2814            |u: &mut User| Some(&mut u.scores),
2815        );
2816
2817        // Test any
2818        let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2819        assert!(has_high_fn(&user_high));
2820        assert!(has_high_fn(&user_mixed));
2821
2822        // Test all
2823        let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2824        assert!(all_passing_fn(&user_high));
2825        assert!(!all_passing_fn(&user_mixed));
2826    }
2827
2828    #[test]
2829    fn test_kp_count_items() {
2830        #[derive(Debug)]
2831        struct User {
2832            tags: Vec<String>,
2833        }
2834
2835        let user = User {
2836            tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2837        };
2838
2839        let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2840        let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2841
2842        assert_eq!(count_fn(&user), Some(3));
2843    }
2844
2845    #[test]
2846    fn test_kp_find_in() {
2847        #[derive(Debug)]
2848        struct User {
2849            scores: Vec<i32>,
2850        }
2851
2852        let user = User {
2853            scores: vec![85, 92, 78, 95, 88],
2854        };
2855
2856        let scores_kp = KpType::new(
2857            |u: &User| Some(&u.scores),
2858            |u: &mut User| Some(&mut u.scores),
2859        );
2860
2861        // Find first score > 90
2862        let first_high_fn =
2863            scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2864
2865        assert_eq!(first_high_fn(&user), Some(92));
2866
2867        // Find score > 100 (doesn't exist)
2868        let perfect_fn =
2869            scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2870
2871        assert_eq!(perfect_fn(&user), None);
2872    }
2873
2874    #[test]
2875    fn test_kp_take_skip() {
2876        #[derive(Debug)]
2877        struct User {
2878            tags: Vec<String>,
2879        }
2880
2881        let user = User {
2882            tags: vec![
2883                "a".to_string(),
2884                "b".to_string(),
2885                "c".to_string(),
2886                "d".to_string(),
2887            ],
2888        };
2889
2890        let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2891
2892        // Take first 2
2893        let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2894            tags.iter().take(n).cloned().collect::<Vec<_>>()
2895        });
2896
2897        let taken = take_fn(&user).unwrap();
2898        assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2899
2900        // Skip first 2
2901        let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2902            tags.iter().skip(n).cloned().collect::<Vec<_>>()
2903        });
2904
2905        let skipped = skip_fn(&user).unwrap();
2906        assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2907    }
2908
2909    #[test]
2910    fn test_kp_partition() {
2911        #[derive(Debug)]
2912        struct User {
2913            scores: Vec<i32>,
2914        }
2915
2916        let user = User {
2917            scores: vec![85, 92, 65, 95, 72, 58],
2918        };
2919
2920        let scores_kp = KpType::new(
2921            |u: &User| Some(&u.scores),
2922            |u: &mut User| Some(&mut u.scores),
2923        );
2924
2925        let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2926            scores.iter().copied().partition(|&s| s >= 70)
2927        });
2928
2929        let (passing, failing) = partition_fn(&user).unwrap();
2930        assert_eq!(passing, vec![85, 92, 95, 72]);
2931        assert_eq!(failing, vec![65, 58]);
2932    }
2933
2934    #[test]
2935    fn test_kp_min_max() {
2936        #[derive(Debug)]
2937        struct User {
2938            scores: Vec<i32>,
2939        }
2940
2941        let user = User {
2942            scores: vec![85, 92, 78, 95, 88],
2943        };
2944
2945        let scores_kp = KpType::new(
2946            |u: &User| Some(&u.scores),
2947            |u: &mut User| Some(&mut u.scores),
2948        );
2949
2950        // Min
2951        let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
2952        assert_eq!(min_fn(&user), Some(78));
2953
2954        // Max
2955        let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
2956        assert_eq!(max_fn(&user), Some(95));
2957    }
2958
2959    #[test]
2960    fn test_kp_sum() {
2961        #[derive(Debug)]
2962        struct User {
2963            scores: Vec<i32>,
2964        }
2965
2966        let user = User {
2967            scores: vec![85, 92, 78],
2968        };
2969
2970        let scores_kp = KpType::new(
2971            |u: &User| Some(&u.scores),
2972            |u: &mut User| Some(&mut u.scores),
2973        );
2974
2975        let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
2976        assert_eq!(sum_fn(&user), Some(255));
2977
2978        // Average
2979        let avg_fn =
2980            scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2981        assert_eq!(avg_fn.get(&user), Some(85));
2982    }
2983
2984    #[test]
2985    fn test_kp_chain() {
2986        #[derive(Debug)]
2987        struct User {
2988            profile: Profile,
2989        }
2990
2991        #[derive(Debug)]
2992        struct Profile {
2993            settings: Settings,
2994        }
2995
2996        #[derive(Debug)]
2997        struct Settings {
2998            theme: String,
2999        }
3000
3001        let user = User {
3002            profile: Profile {
3003                settings: Settings {
3004                    theme: "dark".to_string(),
3005                },
3006            },
3007        };
3008
3009        let profile_kp = KpType::new(
3010            |u: &User| Some(&u.profile),
3011            |u: &mut User| Some(&mut u.profile),
3012        );
3013        let settings_kp = KpType::new(
3014            |p: &Profile| Some(&p.settings),
3015            |p: &mut Profile| Some(&mut p.settings),
3016        );
3017        let theme_kp = KpType::new(
3018            |s: &Settings| Some(&s.theme),
3019            |s: &mut Settings| Some(&mut s.theme),
3020        );
3021
3022        // Chain all together - store intermediate result
3023        let profile_settings = profile_kp.chain(settings_kp);
3024        let theme_path = profile_settings.chain(theme_kp);
3025        assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3026    }
3027
3028    #[test]
3029    fn test_kp_zip() {
3030        #[derive(Debug)]
3031        struct User {
3032            name: String,
3033            age: i32,
3034        }
3035
3036        let user = User {
3037            name: "Alice".to_string(),
3038            age: 30,
3039        };
3040
3041        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3042        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3043
3044        let zipped_fn = zip_kps(&name_kp, &age_kp);
3045        let result = zipped_fn(&user);
3046
3047        assert_eq!(result, Some((&"Alice".to_string(), &30)));
3048    }
3049
3050    #[test]
3051    fn test_kp_complex_pipeline() {
3052        #[derive(Debug)]
3053        struct User {
3054            transactions: Vec<Transaction>,
3055        }
3056
3057        #[derive(Debug)]
3058        struct Transaction {
3059            amount: f64,
3060            category: String,
3061        }
3062
3063        let user = User {
3064            transactions: vec![
3065                Transaction {
3066                    amount: 50.0,
3067                    category: "food".to_string(),
3068                },
3069                Transaction {
3070                    amount: 100.0,
3071                    category: "transport".to_string(),
3072                },
3073                Transaction {
3074                    amount: 25.0,
3075                    category: "food".to_string(),
3076                },
3077                Transaction {
3078                    amount: 200.0,
3079                    category: "shopping".to_string(),
3080                },
3081            ],
3082        };
3083
3084        let txns_kp = KpType::new(
3085            |u: &User| Some(&u.transactions),
3086            |u: &mut User| Some(&mut u.transactions),
3087        );
3088
3089        // Calculate total food expenses
3090        let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3091            txns.iter()
3092                .filter(|t| t.category == "food")
3093                .map(|t| t.amount)
3094                .sum::<f64>()
3095        });
3096
3097        assert_eq!(food_total.get(&user), Some(75.0));
3098
3099        // Check if any transaction is over 150
3100        let has_large =
3101            txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3102
3103        assert!(has_large(&user));
3104
3105        // Count transactions
3106        let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3107        assert_eq!(count(&user), Some(4));
3108    }
3109
3110    // ========== COPY AND 'STATIC TRAIT BOUND TESTS ==========
3111    // These tests verify that Copy and 'static bounds don't cause cloning or memory leaks
3112
3113    #[test]
3114    fn test_no_clone_required_for_root() {
3115        use std::sync::Arc;
3116        use std::sync::atomic::{AtomicUsize, Ordering};
3117
3118        // Create a type that is NOT Clone and NOT Copy
3119        // If operations clone unnecessarily, this will fail to compile
3120        struct NonCloneableRoot {
3121            data: Arc<AtomicUsize>,
3122            cached_value: usize,
3123        }
3124
3125        impl NonCloneableRoot {
3126            fn new() -> Self {
3127                Self {
3128                    data: Arc::new(AtomicUsize::new(42)),
3129                    cached_value: 42,
3130                }
3131            }
3132
3133            fn increment(&mut self) {
3134                self.data.fetch_add(1, Ordering::SeqCst);
3135                self.cached_value = self.data.load(Ordering::SeqCst);
3136            }
3137
3138            fn get_value(&self) -> &usize {
3139                &self.cached_value
3140            }
3141
3142            fn get_value_mut(&mut self) -> &mut usize {
3143                &mut self.cached_value
3144            }
3145        }
3146
3147        let mut root = NonCloneableRoot::new();
3148
3149        // Create a keypath - this works because we only need &Root, not Clone
3150        let data_kp = KpType::new(
3151            |r: &NonCloneableRoot| Some(r.get_value()),
3152            |r: &mut NonCloneableRoot| {
3153                r.increment();
3154                Some(r.get_value_mut())
3155            },
3156        );
3157
3158        // Test that we can use the keypath without cloning
3159        assert_eq!(data_kp.get(&root), Some(&42));
3160
3161        {
3162            // Test map - no cloning of root happens
3163            let doubled = data_kp.map(|val: &usize| val * 2);
3164            assert_eq!(doubled.get(&root), Some(84));
3165
3166            // Test filter - no cloning of root happens
3167            let filtered = data_kp.filter(|val: &usize| *val > 0);
3168            assert_eq!(filtered.get(&root), Some(&42));
3169        } // Drop derived keypaths
3170
3171        // Test mutable access - no cloning happens
3172        let value_ref = data_kp.get_mut(&mut root);
3173        assert!(value_ref.is_some());
3174    }
3175
3176    #[test]
3177    fn test_no_clone_required_for_value() {
3178        use std::sync::Arc;
3179        use std::sync::atomic::{AtomicUsize, Ordering};
3180
3181        // Value type that is NOT Clone and NOT Copy
3182        struct NonCloneableValue {
3183            counter: Arc<AtomicUsize>,
3184        }
3185
3186        impl NonCloneableValue {
3187            fn new(val: usize) -> Self {
3188                Self {
3189                    counter: Arc::new(AtomicUsize::new(val)),
3190                }
3191            }
3192
3193            fn get(&self) -> usize {
3194                self.counter.load(Ordering::SeqCst)
3195            }
3196        }
3197
3198        struct Root {
3199            value: NonCloneableValue,
3200        }
3201
3202        let root = Root {
3203            value: NonCloneableValue::new(100),
3204        };
3205
3206        // Keypath that returns reference to non-cloneable value
3207        let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3208
3209        // Map to extract the counter value - no cloning happens
3210        let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3211        assert_eq!(counter_kp.get(&root), Some(100));
3212
3213        // Filter non-cloneable values - no cloning happens
3214        let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3215        assert!(filtered.get(&root).is_some());
3216    }
3217
3218    #[test]
3219    fn test_static_does_not_leak_memory() {
3220        use std::sync::Arc;
3221        use std::sync::atomic::{AtomicUsize, Ordering};
3222
3223        // Track number of instances created and dropped
3224        static CREATED: AtomicUsize = AtomicUsize::new(0);
3225        static DROPPED: AtomicUsize = AtomicUsize::new(0);
3226
3227        struct Tracked {
3228            id: usize,
3229        }
3230
3231        impl Tracked {
3232            fn new() -> Self {
3233                let id = CREATED.fetch_add(1, Ordering::SeqCst);
3234                Self { id }
3235            }
3236        }
3237
3238        impl Drop for Tracked {
3239            fn drop(&mut self) {
3240                DROPPED.fetch_add(1, Ordering::SeqCst);
3241            }
3242        }
3243
3244        struct Root {
3245            data: Tracked,
3246        }
3247
3248        // Reset counters
3249        CREATED.store(0, Ordering::SeqCst);
3250        DROPPED.store(0, Ordering::SeqCst);
3251
3252        {
3253            let root = Root {
3254                data: Tracked::new(),
3255            };
3256
3257            let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3258
3259            // Use map multiple times
3260            let mapped1 = data_kp.map(|t: &Tracked| t.id);
3261            let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3262            let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3263
3264            assert_eq!(mapped1.get(&root), Some(0));
3265            assert_eq!(mapped2.get(&root), Some(1));
3266            assert_eq!(mapped3.get(&root), Some(2));
3267
3268            // Only 1 instance should be created (the one in root)
3269            assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3270            assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3271        }
3272
3273        // After root is dropped, exactly 1 drop should happen
3274        assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3275        assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3276
3277        // No memory leaks - created == dropped
3278    }
3279
3280    #[test]
3281    fn test_references_not_cloned() {
3282        use std::sync::Arc;
3283
3284        // Large data structure that would be expensive to clone
3285        struct ExpensiveData {
3286            large_vec: Vec<u8>,
3287        }
3288
3289        impl ExpensiveData {
3290            fn new(size: usize) -> Self {
3291                Self {
3292                    large_vec: vec![0u8; size],
3293                }
3294            }
3295
3296            fn size(&self) -> usize {
3297                self.large_vec.len()
3298            }
3299        }
3300
3301        struct Root {
3302            expensive: ExpensiveData,
3303        }
3304
3305        let root = Root {
3306            expensive: ExpensiveData::new(1_000_000), // 1MB
3307        };
3308
3309        let expensive_kp = KpType::new(
3310            |r: &Root| Some(&r.expensive),
3311            |r: &mut Root| Some(&mut r.expensive),
3312        );
3313
3314        // Map operations work with references - no cloning of ExpensiveData
3315        let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3316        assert_eq!(size_kp.get(&root), Some(1_000_000));
3317
3318        // Filter also works with references - no cloning
3319        let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3320        assert!(large_filter.get(&root).is_some());
3321
3322        // All operations work through references - no expensive clones happen
3323    }
3324
3325    #[test]
3326    fn test_hof_with_arc_no_extra_clones() {
3327        use std::sync::Arc;
3328
3329        #[derive(Debug)]
3330        struct SharedData {
3331            value: String,
3332        }
3333
3334        struct Root {
3335            shared: Arc<SharedData>,
3336        }
3337
3338        let shared = Arc::new(SharedData {
3339            value: "shared".to_string(),
3340        });
3341
3342        // Check initial reference count
3343        assert_eq!(Arc::strong_count(&shared), 1);
3344
3345        {
3346            let root = Root {
3347                shared: Arc::clone(&shared),
3348            };
3349
3350            // Reference count is now 2
3351            assert_eq!(Arc::strong_count(&shared), 2);
3352
3353            let shared_kp = KpType::new(
3354                |r: &Root| Some(&r.shared),
3355                |r: &mut Root| Some(&mut r.shared),
3356            );
3357
3358            // Map operation - should not increase Arc refcount
3359            let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3360
3361            // Using the keypath doesn't increase refcount
3362            assert_eq!(value_kp.get(&root), Some(6));
3363            assert_eq!(Arc::strong_count(&shared), 2); // Still just 2
3364
3365            // Filter operation - should not increase Arc refcount
3366            let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3367            assert!(filtered.get(&root).is_some());
3368            assert_eq!(Arc::strong_count(&shared), 2); // Still just 2
3369        } // root is dropped here
3370
3371        assert_eq!(Arc::strong_count(&shared), 1); // Back to 1
3372    }
3373
3374    #[test]
3375    fn test_closure_captures_not_root_values() {
3376        use std::sync::Arc;
3377        use std::sync::atomic::{AtomicUsize, Ordering};
3378
3379        // Track how many times the closure is called
3380        let call_count = Arc::new(AtomicUsize::new(0));
3381        let call_count_clone = Arc::clone(&call_count);
3382
3383        struct Root {
3384            value: i32,
3385        }
3386
3387        let root = Root { value: 42 };
3388
3389        let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3390
3391        // Use fold_value which doesn't require Copy (optimized HOF)
3392        // The closure captures call_count (via move), not the root or value
3393        let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3394            call_count_clone.fetch_add(1, Ordering::SeqCst);
3395            v * 2
3396        });
3397
3398        // Call multiple times
3399        assert_eq!(doubled(&root), 84);
3400        assert_eq!(doubled(&root), 84);
3401        assert_eq!(doubled(&root), 84);
3402
3403        // Closure was called 3 times
3404        assert_eq!(call_count.load(Ordering::SeqCst), 3);
3405
3406        // The Root and value were NOT cloned - only references were passed
3407    }
3408
3409    #[test]
3410    fn test_static_with_borrowed_data() {
3411        // 'static doesn't mean the data lives forever
3412        // It means the TYPE doesn't contain non-'static references
3413
3414        struct Root {
3415            data: String,
3416        }
3417
3418        {
3419            let root = Root {
3420                data: "temporary".to_string(),
3421            };
3422
3423            let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3424
3425            // Map with 'static bound - but root is NOT static
3426            let len_kp = data_kp.map(|s: &String| s.len());
3427            assert_eq!(len_kp.get(&root), Some(9));
3428
3429            // When root goes out of scope here, everything is properly dropped
3430        } // root is dropped here along with len_kp
3431
3432        // No memory leak - root was dropped normally
3433    }
3434
3435    #[test]
3436    fn test_multiple_hof_operations_no_accumulation() {
3437        use std::sync::Arc;
3438        use std::sync::atomic::{AtomicUsize, Ordering};
3439
3440        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3441
3442        struct Tracked {
3443            id: usize,
3444        }
3445
3446        impl Drop for Tracked {
3447            fn drop(&mut self) {
3448                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3449            }
3450        }
3451
3452        struct Root {
3453            values: Vec<Tracked>,
3454        }
3455
3456        DROP_COUNT.store(0, Ordering::SeqCst);
3457
3458        {
3459            let root = Root {
3460                values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3461            };
3462
3463            let values_kp = KpType::new(
3464                |r: &Root| Some(&r.values),
3465                |r: &mut Root| Some(&mut r.values),
3466            );
3467
3468            // Multiple HOF operations - should not clone the Vec<Tracked>
3469            let count = values_kp.count_items(|v| v.len());
3470            let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3471            let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3472            let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3473
3474            assert_eq!(count(&root), Some(3));
3475            assert_eq!(sum(&root), Some(6));
3476            assert!(has_2(&root));
3477            assert!(all_positive(&root));
3478
3479            // No drops yet - values are still in root
3480            assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3481        }
3482
3483        // Now exactly 3 Tracked instances should be dropped
3484        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3485    }
3486
3487    #[test]
3488    fn test_copy_bound_only_for_function_not_data() {
3489        // This test verifies that F: Copy means the FUNCTION must be Copy,
3490        // not the data being processed
3491
3492        #[derive(Debug)]
3493        struct NonCopyData {
3494            value: String,
3495        }
3496
3497        struct Root {
3498            data: NonCopyData,
3499        }
3500
3501        let root = Root {
3502            data: NonCopyData {
3503                value: "test".to_string(),
3504            },
3505        };
3506
3507        let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3508
3509        // Map works even though NonCopyData is not Copy
3510        // The function pointer IS Copy, but the data is not
3511        let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3512        assert_eq!(len_kp.get(&root), Some(4));
3513
3514        // Filter also works with non-Copy data
3515        let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3516        assert!(filtered.get(&root).is_some());
3517    }
3518
3519    #[test]
3520    fn test_no_memory_leak_with_cyclic_references() {
3521        use std::sync::atomic::{AtomicUsize, Ordering};
3522        use std::sync::{Arc, Weak};
3523
3524        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3525
3526        struct Node {
3527            id: usize,
3528            parent: Option<Weak<Node>>,
3529        }
3530
3531        impl Drop for Node {
3532            fn drop(&mut self) {
3533                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3534            }
3535        }
3536
3537        struct Root {
3538            node: Arc<Node>,
3539        }
3540
3541        DROP_COUNT.store(0, Ordering::SeqCst);
3542
3543        {
3544            let root = Root {
3545                node: Arc::new(Node {
3546                    id: 1,
3547                    parent: None,
3548                }),
3549            };
3550
3551            let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3552
3553            // Map operations don't create extra Arc clones
3554            let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3555            assert_eq!(id_kp.get(&root), Some(1));
3556
3557            // Strong count should still be 1 (only in root)
3558            assert_eq!(Arc::strong_count(&root.node), 1);
3559
3560            // No drops yet
3561            assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3562        }
3563
3564        // Exactly 1 Node should be dropped
3565        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3566    }
3567
3568    #[test]
3569    fn test_hof_operations_are_zero_cost_abstractions() {
3570        // This test verifies that HOF operations don't add overhead
3571        // by checking that the same number of operations occur
3572
3573        struct Root {
3574            value: i32,
3575        }
3576
3577        let root = Root { value: 10 };
3578
3579        let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3580
3581        // Direct access
3582        let direct_result = value_kp.get(&root).map(|v| v * 2);
3583        assert_eq!(direct_result, Some(20));
3584
3585        // Through map HOF
3586        let mapped_kp = value_kp.map(|v: &i32| v * 2);
3587        let hof_result = mapped_kp.get(&root);
3588        assert_eq!(hof_result, Some(20));
3589
3590        // Results are identical - no extra allocations or operations
3591        assert_eq!(direct_result, hof_result);
3592    }
3593
3594    #[test]
3595    fn test_complex_closure_captures_allowed() {
3596        use std::sync::Arc;
3597
3598        // With Copy removed from many HOFs, we can now capture complex state
3599        struct Root {
3600            scores: Vec<i32>,
3601        }
3602
3603        let root = Root {
3604            scores: vec![85, 92, 78, 95, 88],
3605        };
3606
3607        let scores_kp = KpType::new(
3608            |r: &Root| Some(&r.scores),
3609            |r: &mut Root| Some(&mut r.scores),
3610        );
3611
3612        // Capture external state in HOF (only works because Copy was removed)
3613        let threshold = 90;
3614        let multiplier = Arc::new(2);
3615
3616        // These closures capture state but don't need Copy
3617        let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3618            let high: i32 = scores
3619                .iter()
3620                .filter(|&&s| s >= threshold)
3621                .map(|&s| s * *multiplier)
3622                .sum();
3623            acc + high
3624        });
3625
3626        // (92 * 2) + (95 * 2) = 184 + 190 = 374
3627        assert_eq!(high_scores_doubled(&root), 374);
3628    }
3629
3630    // ========== TYPE FILTERING TESTS FOR PKP AND AKP ==========
3631    // These tests demonstrate filtering collections by TypeId
3632
3633    #[test]
3634    fn test_pkp_filter_by_value_type() {
3635        use std::any::TypeId;
3636
3637        #[derive(Debug)]
3638        struct User {
3639            name: String,
3640            age: i32,
3641            score: f64,
3642            active: bool,
3643        }
3644
3645        let user = User {
3646            name: "Alice".to_string(),
3647            age: 30,
3648            score: 95.5,
3649            active: true,
3650        };
3651
3652        // Create keypaths for different fields with different types
3653        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3654        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3655        let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3656        let active_kp = KpType::new(
3657            |u: &User| Some(&u.active),
3658            |u: &mut User| Some(&mut u.active),
3659        );
3660
3661        // Convert to partial keypaths and store in a heterogeneous collection
3662        let all_keypaths: Vec<PKp<User>> = vec![
3663            PKp::new(name_kp),
3664            PKp::new(age_kp),
3665            PKp::new(score_kp),
3666            PKp::new(active_kp),
3667        ];
3668
3669        // Filter for String types
3670        let string_kps: Vec<_> = all_keypaths
3671            .iter()
3672            .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3673            .collect();
3674
3675        assert_eq!(string_kps.len(), 1);
3676        assert_eq!(
3677            string_kps[0].get_as::<String>(&user),
3678            Some(&"Alice".to_string())
3679        );
3680
3681        // Filter for i32 types
3682        let i32_kps: Vec<_> = all_keypaths
3683            .iter()
3684            .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3685            .collect();
3686
3687        assert_eq!(i32_kps.len(), 1);
3688        assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3689
3690        // Filter for f64 types
3691        let f64_kps: Vec<_> = all_keypaths
3692            .iter()
3693            .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3694            .collect();
3695
3696        assert_eq!(f64_kps.len(), 1);
3697        assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3698
3699        // Filter for bool types
3700        let bool_kps: Vec<_> = all_keypaths
3701            .iter()
3702            .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3703            .collect();
3704
3705        assert_eq!(bool_kps.len(), 1);
3706        assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3707    }
3708
3709    #[test]
3710    fn test_pkp_filter_by_struct_type() {
3711        use std::any::TypeId;
3712
3713        #[derive(Debug, PartialEq)]
3714        struct Address {
3715            street: String,
3716            city: String,
3717        }
3718
3719        #[derive(Debug)]
3720        struct User {
3721            name: String,
3722            age: i32,
3723            address: Address,
3724        }
3725
3726        let user = User {
3727            name: "Bob".to_string(),
3728            age: 25,
3729            address: Address {
3730                street: "123 Main St".to_string(),
3731                city: "NYC".to_string(),
3732            },
3733        };
3734
3735        // Create keypaths for different types
3736        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3737        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3738        let address_kp = KpType::new(
3739            |u: &User| Some(&u.address),
3740            |u: &mut User| Some(&mut u.address),
3741        );
3742
3743        let all_keypaths: Vec<PKp<User>> =
3744            vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3745
3746        // Filter for custom struct type (Address)
3747        let struct_kps: Vec<_> = all_keypaths
3748            .iter()
3749            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3750            .collect();
3751
3752        assert_eq!(struct_kps.len(), 1);
3753        assert_eq!(
3754            struct_kps[0].get_as::<Address>(&user),
3755            Some(&Address {
3756                street: "123 Main St".to_string(),
3757                city: "NYC".to_string(),
3758            })
3759        );
3760
3761        // Filter for primitive types (non-struct)
3762        let primitive_kps: Vec<_> = all_keypaths
3763            .iter()
3764            .filter(|pkp| {
3765                pkp.value_type_id() == TypeId::of::<String>()
3766                    || pkp.value_type_id() == TypeId::of::<i32>()
3767            })
3768            .collect();
3769
3770        assert_eq!(primitive_kps.len(), 2);
3771    }
3772
3773    #[test]
3774    fn test_pkp_filter_by_arc_type() {
3775        use std::any::TypeId;
3776        use std::sync::Arc;
3777
3778        #[derive(Debug)]
3779        struct User {
3780            name: String,
3781            shared_data: Arc<String>,
3782            shared_number: Arc<i32>,
3783        }
3784
3785        let user = User {
3786            name: "Charlie".to_string(),
3787            shared_data: Arc::new("shared".to_string()),
3788            shared_number: Arc::new(42),
3789        };
3790
3791        // Create keypaths for different types including Arc
3792        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3793        let shared_data_kp = KpType::new(
3794            |u: &User| Some(&u.shared_data),
3795            |u: &mut User| Some(&mut u.shared_data),
3796        );
3797        let shared_number_kp = KpType::new(
3798            |u: &User| Some(&u.shared_number),
3799            |u: &mut User| Some(&mut u.shared_number),
3800        );
3801
3802        let all_keypaths: Vec<PKp<User>> = vec![
3803            PKp::new(name_kp),
3804            PKp::new(shared_data_kp),
3805            PKp::new(shared_number_kp),
3806        ];
3807
3808        // Filter for Arc<String> types
3809        let arc_string_kps: Vec<_> = all_keypaths
3810            .iter()
3811            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3812            .collect();
3813
3814        assert_eq!(arc_string_kps.len(), 1);
3815        assert_eq!(
3816            arc_string_kps[0]
3817                .get_as::<Arc<String>>(&user)
3818                .map(|arc| arc.as_str()),
3819            Some("shared")
3820        );
3821
3822        // Filter for Arc<i32> types
3823        let arc_i32_kps: Vec<_> = all_keypaths
3824            .iter()
3825            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3826            .collect();
3827
3828        assert_eq!(arc_i32_kps.len(), 1);
3829        assert_eq!(
3830            arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3831            Some(42)
3832        );
3833
3834        // Filter for all Arc types (any T)
3835        let all_arc_kps: Vec<_> = all_keypaths
3836            .iter()
3837            .filter(|pkp| {
3838                pkp.value_type_id() == TypeId::of::<Arc<String>>()
3839                    || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3840            })
3841            .collect();
3842
3843        assert_eq!(all_arc_kps.len(), 2);
3844    }
3845
3846    #[test]
3847    fn test_pkp_filter_by_box_type() {
3848        use std::any::TypeId;
3849
3850        #[derive(Debug)]
3851        struct User {
3852            name: String,
3853            boxed_value: Box<i32>,
3854            boxed_string: Box<String>,
3855        }
3856
3857        let user = User {
3858            name: "Diana".to_string(),
3859            boxed_value: Box::new(100),
3860            boxed_string: Box::new("boxed".to_string()),
3861        };
3862
3863        // Create keypaths
3864        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3865        let boxed_value_kp = KpType::new(
3866            |u: &User| Some(&u.boxed_value),
3867            |u: &mut User| Some(&mut u.boxed_value),
3868        );
3869        let boxed_string_kp = KpType::new(
3870            |u: &User| Some(&u.boxed_string),
3871            |u: &mut User| Some(&mut u.boxed_string),
3872        );
3873
3874        let all_keypaths: Vec<PKp<User>> = vec![
3875            PKp::new(name_kp),
3876            PKp::new(boxed_value_kp),
3877            PKp::new(boxed_string_kp),
3878        ];
3879
3880        // Filter for Box<i32>
3881        let box_i32_kps: Vec<_> = all_keypaths
3882            .iter()
3883            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3884            .collect();
3885
3886        assert_eq!(box_i32_kps.len(), 1);
3887        assert_eq!(
3888            box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3889            Some(100)
3890        );
3891
3892        // Filter for Box<String>
3893        let box_string_kps: Vec<_> = all_keypaths
3894            .iter()
3895            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3896            .collect();
3897
3898        assert_eq!(box_string_kps.len(), 1);
3899        assert_eq!(
3900            box_string_kps[0]
3901                .get_as::<Box<String>>(&user)
3902                .map(|b| b.as_str()),
3903            Some("boxed")
3904        );
3905    }
3906
3907    #[test]
3908    fn test_akp_filter_by_root_and_value_type() {
3909        use std::any::TypeId;
3910
3911        #[derive(Debug)]
3912        struct User {
3913            name: String,
3914            age: i32,
3915        }
3916
3917        #[derive(Debug)]
3918        struct Product {
3919            title: String,
3920            price: f64,
3921        }
3922
3923        let user = User {
3924            name: "Eve".to_string(),
3925            age: 28,
3926        };
3927
3928        let product = Product {
3929            title: "Book".to_string(),
3930            price: 19.99,
3931        };
3932
3933        // Create AnyKeypaths for different root/value type combinations
3934        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3935        let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3936        let product_title_kp = KpType::new(
3937            |p: &Product| Some(&p.title),
3938            |p: &mut Product| Some(&mut p.title),
3939        );
3940        let product_price_kp = KpType::new(
3941            |p: &Product| Some(&p.price),
3942            |p: &mut Product| Some(&mut p.price),
3943        );
3944
3945        let all_keypaths: Vec<AKp> = vec![
3946            AKp::new(user_name_kp),
3947            AKp::new(user_age_kp),
3948            AKp::new(product_title_kp),
3949            AKp::new(product_price_kp),
3950        ];
3951
3952        // Filter for User root type
3953        let user_kps: Vec<_> = all_keypaths
3954            .iter()
3955            .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
3956            .collect();
3957
3958        assert_eq!(user_kps.len(), 2);
3959
3960        // Filter for Product root type
3961        let product_kps: Vec<_> = all_keypaths
3962            .iter()
3963            .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
3964            .collect();
3965
3966        assert_eq!(product_kps.len(), 2);
3967
3968        // Filter for String value type
3969        let string_value_kps: Vec<_> = all_keypaths
3970            .iter()
3971            .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
3972            .collect();
3973
3974        assert_eq!(string_value_kps.len(), 2);
3975
3976        // Filter for both User root AND String value
3977        let user_string_kps: Vec<_> = all_keypaths
3978            .iter()
3979            .filter(|akp| {
3980                akp.root_type_id() == TypeId::of::<User>()
3981                    && akp.value_type_id() == TypeId::of::<String>()
3982            })
3983            .collect();
3984
3985        assert_eq!(user_string_kps.len(), 1);
3986        assert_eq!(
3987            user_string_kps[0].get_as::<User, String>(&user),
3988            Some(Some(&"Eve".to_string()))
3989        );
3990
3991        // Filter for Product root AND f64 value
3992        let product_f64_kps: Vec<_> = all_keypaths
3993            .iter()
3994            .filter(|akp| {
3995                akp.root_type_id() == TypeId::of::<Product>()
3996                    && akp.value_type_id() == TypeId::of::<f64>()
3997            })
3998            .collect();
3999
4000        assert_eq!(product_f64_kps.len(), 1);
4001        assert_eq!(
4002            product_f64_kps[0].get_as::<Product, f64>(&product),
4003            Some(Some(&19.99))
4004        );
4005    }
4006
4007    #[test]
4008    fn test_akp_filter_by_arc_root_type() {
4009        use std::any::TypeId;
4010        use std::sync::Arc;
4011
4012        #[derive(Debug)]
4013        struct User {
4014            name: String,
4015        }
4016
4017        #[derive(Debug)]
4018        struct Product {
4019            title: String,
4020        }
4021
4022        let user = User {
4023            name: "Frank".to_string(),
4024        };
4025        let product = Product {
4026            title: "Laptop".to_string(),
4027        };
4028
4029        // Create keypaths
4030        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4031        let product_title_kp = KpType::new(
4032            |p: &Product| Some(&p.title),
4033            |p: &mut Product| Some(&mut p.title),
4034        );
4035
4036        // Create AKp and adapt for Arc
4037        let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4038        let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4039
4040        let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4041
4042        // Filter for Arc<User> root type
4043        let arc_user_kps: Vec<_> = all_keypaths
4044            .iter()
4045            .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4046            .collect();
4047
4048        assert_eq!(arc_user_kps.len(), 1);
4049
4050        // Verify it works with Arc<User>
4051        let arc_user = Arc::new(user);
4052        assert_eq!(
4053            arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4054            Some(Some(&"Frank".to_string()))
4055        );
4056
4057        // Filter for Arc<Product> root type
4058        let arc_product_kps: Vec<_> = all_keypaths
4059            .iter()
4060            .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4061            .collect();
4062
4063        assert_eq!(arc_product_kps.len(), 1);
4064
4065        // Verify it works with Arc<Product>
4066        let arc_product = Arc::new(product);
4067        assert_eq!(
4068            arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4069            Some(Some(&"Laptop".to_string()))
4070        );
4071    }
4072
4073    #[test]
4074    fn test_akp_filter_by_box_root_type() {
4075        use std::any::TypeId;
4076
4077        #[derive(Debug)]
4078        struct Config {
4079            setting: String,
4080        }
4081
4082        let config = Config {
4083            setting: "enabled".to_string(),
4084        };
4085
4086        // Create keypath for regular Config
4087        let config_kp1 = KpType::new(
4088            |c: &Config| Some(&c.setting),
4089            |c: &mut Config| Some(&mut c.setting),
4090        );
4091        let config_kp2 = KpType::new(
4092            |c: &Config| Some(&c.setting),
4093            |c: &mut Config| Some(&mut c.setting),
4094        );
4095
4096        // Create both regular and Box-adapted AKp
4097        let regular_akp = AKp::new(config_kp1);
4098        let box_akp = AKp::new(config_kp2).for_box::<Config>();
4099
4100        let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4101
4102        // Filter for Config root type
4103        let config_kps: Vec<_> = all_keypaths
4104            .iter()
4105            .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4106            .collect();
4107
4108        assert_eq!(config_kps.len(), 1);
4109        assert_eq!(
4110            config_kps[0].get_as::<Config, String>(&config),
4111            Some(Some(&"enabled".to_string()))
4112        );
4113
4114        // Filter for Box<Config> root type
4115        let box_config_kps: Vec<_> = all_keypaths
4116            .iter()
4117            .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4118            .collect();
4119
4120        assert_eq!(box_config_kps.len(), 1);
4121
4122        // Verify it works with Box<Config>
4123        let box_config = Box::new(Config {
4124            setting: "enabled".to_string(),
4125        });
4126        assert_eq!(
4127            box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4128            Some(Some(&"enabled".to_string()))
4129        );
4130    }
4131
4132    #[test]
4133    fn test_mixed_collection_type_filtering() {
4134        use std::any::TypeId;
4135        use std::sync::Arc;
4136
4137        #[derive(Debug)]
4138        struct User {
4139            name: String,
4140            email: String,
4141        }
4142
4143        #[derive(Debug)]
4144        struct Product {
4145            title: String,
4146            sku: String,
4147        }
4148
4149        let user = User {
4150            name: "Grace".to_string(),
4151            email: "grace@example.com".to_string(),
4152        };
4153
4154        let product = Product {
4155            title: "Widget".to_string(),
4156            sku: "WID-001".to_string(),
4157        };
4158
4159        // Create a complex heterogeneous collection
4160        let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4161        let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4162        let user_email_kp1 =
4163            KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4164        let user_email_kp2 =
4165            KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4166        let product_title_kp = KpType::new(
4167            |p: &Product| Some(&p.title),
4168            |p: &mut Product| Some(&mut p.title),
4169        );
4170        let product_sku_kp = KpType::new(
4171            |p: &Product| Some(&p.sku),
4172            |p: &mut Product| Some(&mut p.sku),
4173        );
4174
4175        let all_keypaths: Vec<AKp> = vec![
4176            AKp::new(user_name_kp1),
4177            AKp::new(user_email_kp1),
4178            AKp::new(product_title_kp),
4179            AKp::new(product_sku_kp),
4180            AKp::new(user_name_kp2).for_arc::<User>(),
4181            AKp::new(user_email_kp2).for_box::<User>(),
4182        ];
4183
4184        // Test 1: Find all keypaths with String values
4185        let string_value_kps: Vec<_> = all_keypaths
4186            .iter()
4187            .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4188            .collect();
4189
4190        assert_eq!(string_value_kps.len(), 6); // All return String
4191
4192        // Test 2: Find keypaths with User root (excluding Arc<User> and Box<User>)
4193        let user_root_kps: Vec<_> = all_keypaths
4194            .iter()
4195            .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4196            .collect();
4197
4198        assert_eq!(user_root_kps.len(), 2);
4199
4200        // Test 3: Find keypaths with Arc<User> root
4201        let arc_user_kps: Vec<_> = all_keypaths
4202            .iter()
4203            .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4204            .collect();
4205
4206        assert_eq!(arc_user_kps.len(), 1);
4207
4208        // Test 4: Find keypaths with Box<User> root
4209        let box_user_kps: Vec<_> = all_keypaths
4210            .iter()
4211            .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4212            .collect();
4213
4214        assert_eq!(box_user_kps.len(), 1);
4215
4216        // Test 5: Find Product keypaths (non-wrapped)
4217        let product_kps: Vec<_> = all_keypaths
4218            .iter()
4219            .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4220            .collect();
4221
4222        assert_eq!(product_kps.len(), 2);
4223
4224        // Test 6: Verify we can use the filtered keypaths
4225        let user_value = user_root_kps[0].get_as::<User, String>(&user);
4226        assert!(user_value.is_some());
4227        assert!(user_value.unwrap().is_some());
4228    }
4229
4230    // ========================================================================
4231    // Advanced Type Examples: Pin, MaybeUninit, Weak
4232    // ========================================================================
4233
4234    #[test]
4235    fn test_kp_with_pin() {
4236        use std::pin::Pin;
4237
4238        // Pin ensures a value won't be moved in memory
4239        // Useful for self-referential structs and async
4240
4241        #[derive(Debug)]
4242        struct SelfReferential {
4243            value: String,
4244            ptr_to_value: *const String, // Points to value field
4245        }
4246
4247        impl SelfReferential {
4248            fn new(s: String) -> Self {
4249                let mut sr = Self {
4250                    value: s,
4251                    ptr_to_value: std::ptr::null(),
4252                };
4253                // Make it self-referential
4254                sr.ptr_to_value = &sr.value as *const String;
4255                sr
4256            }
4257
4258            fn get_value(&self) -> &str {
4259                &self.value
4260            }
4261        }
4262
4263        // Create a pinned value
4264        let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4265        let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4266
4267        // Keypath to access the value field through Pin
4268        let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4269            |p: &Pin<Box<SelfReferential>>| {
4270                // Pin::as_ref() gives us &SelfReferential
4271                Some(&p.as_ref().get_ref().value)
4272            },
4273            |p: &mut Pin<Box<SelfReferential>>| {
4274                // For mutable access, we need to use unsafe get_unchecked_mut
4275                // In practice, you'd use Pin::get_mut if T: Unpin
4276                unsafe {
4277                    let sr = Pin::get_unchecked_mut(p.as_mut());
4278                    Some(&mut sr.value)
4279                }
4280            },
4281        );
4282
4283        // Access through keypath
4284        let result = kp.get(&pinned);
4285        assert_eq!(result, Some(&"pinned_data".to_string()));
4286
4287        // The value is still pinned and hasn't moved
4288        assert_eq!(pinned.get_value(), "pinned_data");
4289    }
4290
4291    #[test]
4292    fn test_kp_with_pin_arc() {
4293        use std::pin::Pin;
4294        use std::sync::Arc;
4295
4296        struct AsyncState {
4297            status: String,
4298            data: Vec<i32>,
4299        }
4300
4301        // Pin<Arc<T>> is common in async Rust
4302        let state = AsyncState {
4303            status: "ready".to_string(),
4304            data: vec![1, 2, 3, 4, 5],
4305        };
4306
4307        let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4308
4309        // Keypath to status through Pin<Arc<T>>
4310        let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4311            |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4312            |_: &mut Pin<Arc<AsyncState>>| {
4313                // Arc is immutable, so mutable access returns None
4314                None::<&mut String>
4315            },
4316        );
4317
4318        // Keypath to data through Pin<Arc<T>>
4319        let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4320            |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4321            |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4322        );
4323
4324        let status = status_kp.get(&pinned_arc);
4325        assert_eq!(status, Some(&"ready".to_string()));
4326
4327        let data = data_kp.get(&pinned_arc);
4328        assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4329    }
4330
4331    #[test]
4332    fn test_kp_with_maybe_uninit() {
4333        use std::mem::MaybeUninit;
4334
4335        // MaybeUninit<T> represents potentially uninitialized memory
4336        // Useful for optimizing initialization or working with FFI
4337
4338        struct Config {
4339            name: MaybeUninit<String>,
4340            value: MaybeUninit<i32>,
4341            initialized: bool,
4342        }
4343
4344        impl Config {
4345            fn new_uninit() -> Self {
4346                Self {
4347                    name: MaybeUninit::uninit(),
4348                    value: MaybeUninit::uninit(),
4349                    initialized: false,
4350                }
4351            }
4352
4353            fn init(&mut self, name: String, value: i32) {
4354                self.name.write(name);
4355                self.value.write(value);
4356                self.initialized = true;
4357            }
4358
4359            fn get_name(&self) -> Option<&String> {
4360                if self.initialized {
4361                    unsafe { Some(self.name.assume_init_ref()) }
4362                } else {
4363                    None
4364                }
4365            }
4366
4367            fn get_value(&self) -> Option<&i32> {
4368                if self.initialized {
4369                    unsafe { Some(self.value.assume_init_ref()) }
4370                } else {
4371                    None
4372                }
4373            }
4374        }
4375
4376        // Create keypath that safely accesses potentially uninitialized data
4377        let name_kp: KpType<Config, String> = Kp::new(
4378            |c: &Config| c.get_name(),
4379            |c: &mut Config| {
4380                if c.initialized {
4381                    unsafe { Some(c.name.assume_init_mut()) }
4382                } else {
4383                    None
4384                }
4385            },
4386        );
4387
4388        let value_kp: KpType<Config, i32> = Kp::new(
4389            |c: &Config| c.get_value(),
4390            |c: &mut Config| {
4391                if c.initialized {
4392                    unsafe { Some(c.value.assume_init_mut()) }
4393                } else {
4394                    None
4395                }
4396            },
4397        );
4398
4399        // Test with uninitialized config
4400        let uninit_config = Config::new_uninit();
4401        assert_eq!(name_kp.get(&uninit_config), None);
4402        assert_eq!(value_kp.get(&uninit_config), None);
4403
4404        // Test with initialized config
4405        let mut init_config = Config::new_uninit();
4406        init_config.init("test_config".to_string(), 42);
4407
4408        assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4409        assert_eq!(value_kp.get(&init_config), Some(&42));
4410
4411        // Modify through keypath
4412        if let Some(val) = value_kp.get_mut(&mut init_config) {
4413            *val = 100;
4414        }
4415
4416        assert_eq!(value_kp.get(&init_config), Some(&100));
4417    }
4418
4419    #[test]
4420    fn test_kp_with_weak() {
4421        use std::sync::{Arc, Weak};
4422
4423        // Weak references don't prevent deallocation
4424        // For keypaths with Weak, we need to store the strong reference
4425
4426        #[derive(Debug, Clone)]
4427        struct Node {
4428            value: i32,
4429        }
4430
4431        struct NodeWithParent {
4432            value: i32,
4433            parent: Option<Arc<Node>>, // Strong reference for demonstration
4434        }
4435
4436        let parent = Arc::new(Node { value: 100 });
4437
4438        let child = NodeWithParent {
4439            value: 42,
4440            parent: Some(parent.clone()),
4441        };
4442
4443        // Keypath to access parent value
4444        let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4445            |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4446            |_: &mut NodeWithParent| None::<&mut i32>,
4447        );
4448
4449        // Access parent value
4450        let parent_val = parent_value_kp.get(&child);
4451        assert_eq!(parent_val, Some(&100));
4452    }
4453
4454    #[test]
4455    fn test_kp_with_rc_weak() {
4456        use std::rc::Rc;
4457
4458        // Single-threaded version with Rc
4459
4460        struct TreeNode {
4461            value: String,
4462            parent: Option<Rc<TreeNode>>, // Strong ref for keypath access
4463        }
4464
4465        let root = Rc::new(TreeNode {
4466            value: "root".to_string(),
4467            parent: None,
4468        });
4469
4470        let child1 = TreeNode {
4471            value: "child1".to_string(),
4472            parent: Some(root.clone()),
4473        };
4474
4475        let child2 = TreeNode {
4476            value: "child2".to_string(),
4477            parent: Some(root.clone()),
4478        };
4479
4480        // Keypath to access parent's value
4481        let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4482            |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4483            |_: &mut TreeNode| None::<&mut String>,
4484        );
4485
4486        // Access parent
4487        assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4488        assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4489
4490        // Root has no parent
4491        assert_eq!(parent_name_kp.get(&root), None);
4492    }
4493
4494    #[test]
4495    fn test_kp_with_complex_weak_structure() {
4496        use std::sync::Arc;
4497
4498        // Complex structure demonstrating Arc reference patterns
4499
4500        struct Cache {
4501            data: String,
4502            backup: Option<Arc<Cache>>, // Strong reference
4503        }
4504
4505        let primary = Arc::new(Cache {
4506            data: "primary_data".to_string(),
4507            backup: None,
4508        });
4509
4510        let backup = Arc::new(Cache {
4511            data: "backup_data".to_string(),
4512            backup: Some(primary.clone()),
4513        });
4514
4515        // Keypath to access backup's data
4516        let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4517            |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4518            |_: &mut Arc<Cache>| None::<&mut String>,
4519        );
4520
4521        // Access primary data through backup's reference
4522        let data = backup_data_kp.get(&backup);
4523        assert_eq!(data, Some(&"primary_data".to_string()));
4524
4525        // Primary has no backup
4526        let no_backup = backup_data_kp.get(&primary);
4527        assert_eq!(no_backup, None);
4528    }
4529
4530    #[test]
4531    fn test_kp_chain_with_pin_and_arc() {
4532        use std::pin::Pin;
4533        use std::sync::Arc;
4534
4535        // Demonstrate chaining keypaths through Pin and Arc
4536
4537        struct Outer {
4538            inner: Arc<Inner>,
4539        }
4540
4541        struct Inner {
4542            value: String,
4543        }
4544
4545        let outer = Outer {
4546            inner: Arc::new(Inner {
4547                value: "nested_value".to_string(),
4548            }),
4549        };
4550
4551        let pinned_outer = Box::pin(outer);
4552
4553        // First keypath: Pin<Box<Outer>> -> Arc<Inner>
4554        let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4555            |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4556            |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4557        );
4558
4559        // Second keypath: Arc<Inner> -> String
4560        let to_value: KpType<Arc<Inner>, String> = Kp::new(
4561            |a: &Arc<Inner>| Some(&a.value),
4562            |_: &mut Arc<Inner>| None::<&mut String>,
4563        );
4564
4565        // Chain them together
4566        let chained = to_inner.then(to_value);
4567
4568        let result = chained.get(&pinned_outer);
4569        assert_eq!(result, Some(&"nested_value".to_string()));
4570    }
4571
4572    #[test]
4573    fn test_kp_with_maybe_uninit_array() {
4574        use std::mem::MaybeUninit;
4575
4576        // Working with arrays of MaybeUninit - common pattern for
4577        // efficient array initialization
4578
4579        struct Buffer {
4580            data: [MaybeUninit<u8>; 10],
4581            len: usize,
4582        }
4583
4584        impl Buffer {
4585            fn new() -> Self {
4586                Self {
4587                    data: unsafe { MaybeUninit::uninit().assume_init() },
4588                    len: 0,
4589                }
4590            }
4591
4592            fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4593                if self.len >= self.data.len() {
4594                    return Err("Buffer full");
4595                }
4596                self.data[self.len].write(byte);
4597                self.len += 1;
4598                Ok(())
4599            }
4600
4601            fn get(&self, idx: usize) -> Option<&u8> {
4602                if idx < self.len {
4603                    unsafe { Some(self.data[idx].assume_init_ref()) }
4604                } else {
4605                    None
4606                }
4607            }
4608
4609            fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4610                if idx < self.len {
4611                    unsafe { Some(self.data[idx].assume_init_mut()) }
4612                } else {
4613                    None
4614                }
4615            }
4616        }
4617
4618        // Keypath to access length of initialized data
4619        let len_kp: KpType<Buffer, usize> =
4620            Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4621
4622        let mut buffer = Buffer::new();
4623
4624        // Empty buffer
4625        assert_eq!(len_kp.get(&buffer), Some(&0));
4626
4627        // Add some data
4628        buffer.push(1).unwrap();
4629        buffer.push(2).unwrap();
4630        buffer.push(3).unwrap();
4631
4632        // Access through keypath
4633        assert_eq!(len_kp.get(&buffer), Some(&3));
4634
4635        // Access elements directly (not through keypath factory due to type complexity)
4636        assert_eq!(buffer.get(0), Some(&1));
4637        assert_eq!(buffer.get(1), Some(&2));
4638        assert_eq!(buffer.get(2), Some(&3));
4639        assert_eq!(buffer.get(10), None); // Out of bounds
4640
4641        // Modify through buffer's API
4642        if let Some(elem) = buffer.get_mut(1) {
4643            *elem = 20;
4644        }
4645        assert_eq!(buffer.get(1), Some(&20));
4646    }
4647
4648    #[test]
4649    fn test_kp_then_lock_deep_structs() {
4650        use std::sync::{Arc, Mutex};
4651
4652        #[derive(Clone)]
4653        struct Root {
4654            guard: Arc<Mutex<Level1>>,
4655        }
4656        #[derive(Clone)]
4657        struct Level1 {
4658            name: String,
4659            nested: Level2,
4660        }
4661        #[derive(Clone)]
4662        struct Level2 {
4663            count: i32,
4664        }
4665
4666        let root = Root {
4667            guard: Arc::new(Mutex::new(Level1 {
4668                name: "deep".to_string(),
4669                nested: Level2 { count: 42 },
4670            })),
4671        };
4672
4673        let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4674            Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4675
4676        let lock_kp = {
4677            let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4678                Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4679            let next: KpType<Level1, Level1> =
4680                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4681            crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4682        };
4683
4684        let chained = kp_to_guard.then_lock(lock_kp);
4685        let level1 = chained.get(&root);
4686        assert!(level1.is_some());
4687        assert_eq!(level1.unwrap().name, "deep");
4688        assert_eq!(level1.unwrap().nested.count, 42);
4689
4690        let mut_root = &mut root.clone();
4691        let mut_level1 = chained.get_mut(mut_root);
4692        assert!(mut_level1.is_some());
4693        mut_level1.unwrap().nested.count = 99;
4694        assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4695    }
4696
4697    #[test]
4698    fn test_kp_then_lock_with_enum() {
4699        use std::sync::{Arc, Mutex};
4700
4701        #[derive(Clone)]
4702        enum Message {
4703            Request(LevelA),
4704            Response(i32),
4705        }
4706        #[derive(Clone)]
4707        struct LevelA {
4708            data: Arc<Mutex<i32>>,
4709        }
4710
4711        struct RootWithEnum {
4712            msg: Arc<Mutex<Message>>,
4713        }
4714
4715        let root = RootWithEnum {
4716            msg: Arc::new(Mutex::new(Message::Request(LevelA {
4717                data: Arc::new(Mutex::new(100)),
4718            }))),
4719        };
4720
4721        let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4722            Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4723
4724        let lock_kp_msg = {
4725            let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4726                Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4727            let next: KpType<Message, Message> =
4728                Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4729            crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4730        };
4731
4732        let chained = kp_msg.then_lock(lock_kp_msg);
4733        let msg = chained.get(&root);
4734        assert!(msg.is_some());
4735        match msg.unwrap() {
4736            Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4737            Message::Response(_) => panic!("expected Request"),
4738        }
4739    }
4740
4741    #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4742    #[tokio::test]
4743    async fn test_kp_then_async_deep_chain() {
4744        use std::sync::Arc;
4745        use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4746
4747        #[derive(Clone)]
4748        struct Root {
4749            tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4750        }
4751        #[derive(Clone)]
4752        struct Level1 {
4753            value: i32,
4754        }
4755
4756        let root = Root {
4757            tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4758        };
4759
4760        let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4761            |r: &Root| Some(&r.tokio_guard),
4762            |r: &mut Root| Some(&mut r.tokio_guard),
4763        );
4764
4765        let async_kp = {
4766            let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4767                Kp::new(
4768                    |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4769                    |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4770                );
4771            let next: KpType<Level1, Level1> =
4772                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4773            AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4774        };
4775
4776        let chained = kp_to_guard.then_async(async_kp);
4777        let level1 = chained.get(&root).await;
4778        assert!(level1.is_some());
4779        assert_eq!(level1.unwrap().value, 7);
4780    }
4781
4782    /// Deeply nested struct: Root -> sync lock -> L1 -> L2 -> tokio lock -> L3 -> leaf i32.
4783    /// Chain: LockKp(Root->L1) . then(L1->L2) . then(L2->tokio) . then_async(tokio->L3) . then(L3->leaf)
4784    #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4785    #[tokio::test]
4786    async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4787        use std::sync::{Arc, Mutex};
4788        use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4789        use crate::lock::{LockKp, ArcMutexAccess};
4790
4791        // Root -> Arc<Mutex<L1>>
4792        #[derive(Clone)]
4793        struct Root {
4794            sync_mutex: Arc<Mutex<Level1>>,
4795        }
4796        // L1 -> Level2 (plain)
4797        #[derive(Clone)]
4798        struct Level1 {
4799            inner: Level2,
4800        }
4801        // L2 -> Arc<TokioMutex<Level3>>
4802        #[derive(Clone)]
4803        struct Level2 {
4804            tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4805        }
4806        // L3 -> leaf i32
4807        #[derive(Clone)]
4808        struct Level3 {
4809            leaf: i32,
4810        }
4811
4812        let mut root = Root {
4813            sync_mutex: Arc::new(Mutex::new(Level1 {
4814                inner: Level2 {
4815                    tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4816                },
4817            })),
4818        };
4819
4820        // LockKp from Root -> Level1
4821        let identity_l1: KpType<Level1, Level1> =
4822            Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4823        let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
4824            Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
4825        let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4826
4827        // Kp: Level1 -> Level2
4828        let kp_l1_inner: KpType<Level1, Level2> =
4829            Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
4830
4831        // Kp: Level2 -> Arc<TokioMutex<Level3>>
4832        let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4833            |l: &Level2| Some(&l.tokio_mutex),
4834            |l: &mut Level2| Some(&mut l.tokio_mutex),
4835        );
4836
4837        // AsyncKp: Arc<TokioMutex<Level3>> -> Level3
4838        let async_l3 = {
4839            let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4840                Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4841            let next: KpType<Level3, Level3> =
4842                Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4843            AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4844        };
4845
4846        // Kp: Level3 -> i32
4847        let kp_l3_leaf: KpType<Level3, i32> =
4848            Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
4849
4850        // Build chain: LockKp(Root->L1) . then(L1->L2) . then(L2->tokio) . then_async(tokio->L3) . then(L3->leaf)
4851        let step1 = lock_root_to_l1.then(kp_l1_inner);
4852        let step2 = step1.then(kp_l2_tokio);
4853        let step3 = step2.then_async(async_l3);
4854        let deep_chain = step3.then(kp_l3_leaf);
4855
4856        // Read leaf through full chain (async)
4857        let leaf = deep_chain.get(&root).await;
4858        deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4859        assert_eq!(leaf, Some(&100));
4860
4861        // Mutate leaf through full chain
4862        let mut root_mut = root.clone();
4863        let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4864        assert!(leaf_mut.is_some());
4865        *leaf_mut.unwrap() = 99;
4866
4867        // Read back
4868        let leaf_after = deep_chain.get(&root_mut).await;
4869        assert_eq!(leaf_after, Some(&99));
4870    }
4871}