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 kp_f = TestKP::f();
2012        let wres = kp_f.then(TestKP2::a()).get_mut(&mut instance).unwrap();
2013        *wres = String::from("a3 changed successfully");
2014        let res = kp_f.then(TestKP2::a()).get(&instance);
2015        println!("{:?}", res);
2016        let res = kp_f.then(TestKP2::identity()).get(&instance);
2017        println!("{:?}", res);
2018        let res = kp.get(&instance);
2019        println!("{:?}", res);
2020
2021        let hash_kp = TestKP::g(0);
2022        let new_kp_from_hashmap = hash_kp.then(TestKP2::a());
2023        println!("{:?}", new_kp_from_hashmap.get(&instance));
2024    }
2025
2026    // #[test]
2027    // fn test_lock() {
2028    //     let lock_kp = LockKp::new(A::b(), kp_arc_mutex::<B>(), B::c());
2029    //
2030    //     let mut a = A {
2031    //         b: Arc::new(Mutex::new(B {
2032    //             c: C {
2033    //                 d: String::from("hello"),
2034    //             },
2035    //         })),
2036    //     };
2037    //
2038    //     // Get value
2039    //     if let Some(value) = lock_kp.get(&a) {
2040    //         println!("Got: {:?}", value);
2041    //         assert_eq!(value.d, "hello");
2042    //     } else {
2043    //         panic!("Value not found");
2044    //     }
2045    //
2046    //     // Set value using closure
2047    //     let result = lock_kp.set(&a, |d| {
2048    //         d.d.push_str(" world");
2049    //     });
2050    //
2051    //     if result.is_ok() {
2052    //         if let Some(value) = lock_kp.get(&a) {
2053    //             println!("After set: {:?}", value);
2054    //             assert_eq!(value.d, "hello");
2055    //         } else {
2056    //             panic!("Value not found");
2057    //         }
2058    //     }
2059    // }
2060
2061    #[test]
2062    fn test_enum_kp_result_ok() {
2063        let ok_result: Result<String, i32> = Ok("success".to_string());
2064        let mut err_result: Result<String, i32> = Err(42);
2065
2066        let ok_kp = enum_ok();
2067
2068        // Test extraction
2069        assert_eq!(ok_kp.get(&ok_result), Some(&"success".to_string()));
2070        assert_eq!(ok_kp.get(&err_result), None);
2071
2072        // Test embedding
2073        let embedded = ok_kp.embed("embedded".to_string());
2074        assert_eq!(embedded, Ok("embedded".to_string()));
2075
2076        // Test mutable access
2077        if let Some(val) = ok_kp.get_mut(&mut err_result) {
2078            *val = "modified".to_string();
2079        }
2080        assert_eq!(err_result, Err(42)); // Should still be Err
2081
2082        let mut ok_result2 = Ok("original".to_string());
2083        if let Some(val) = ok_kp.get_mut(&mut ok_result2) {
2084            *val = "modified".to_string();
2085        }
2086        assert_eq!(ok_result2, Ok("modified".to_string()));
2087    }
2088
2089    #[test]
2090    fn test_enum_kp_result_err() {
2091        let ok_result: Result<String, i32> = Ok("success".to_string());
2092        let mut err_result: Result<String, i32> = Err(42);
2093
2094        let err_kp = enum_err();
2095
2096        // Test extraction
2097        assert_eq!(err_kp.get(&err_result), Some(&42));
2098        assert_eq!(err_kp.get(&ok_result), None);
2099
2100        // Test embedding
2101        let embedded = err_kp.embed(99);
2102        assert_eq!(embedded, Err(99));
2103
2104        // Test mutable access
2105        if let Some(val) = err_kp.get_mut(&mut err_result) {
2106            *val = 100;
2107        }
2108        assert_eq!(err_result, Err(100));
2109    }
2110
2111    #[test]
2112    fn test_enum_kp_option_some() {
2113        let some_opt = Some("value".to_string());
2114        let mut none_opt: Option<String> = None;
2115
2116        let some_kp = enum_some();
2117
2118        // Test extraction
2119        assert_eq!(some_kp.get(&some_opt), Some(&"value".to_string()));
2120        assert_eq!(some_kp.get(&none_opt), None);
2121
2122        // Test embedding
2123        let embedded = some_kp.embed("embedded".to_string());
2124        assert_eq!(embedded, Some("embedded".to_string()));
2125
2126        // Test mutable access
2127        let mut some_opt2 = Some("original".to_string());
2128        if let Some(val) = some_kp.get_mut(&mut some_opt2) {
2129            *val = "modified".to_string();
2130        }
2131        assert_eq!(some_opt2, Some("modified".to_string()));
2132    }
2133
2134    #[test]
2135    fn test_enum_kp_custom_enum() {
2136        #[derive(Debug, PartialEq)]
2137        enum MyEnum {
2138            A(String),
2139            B(i32),
2140            C,
2141        }
2142
2143        let mut enum_a = MyEnum::A("hello".to_string());
2144        let enum_b = MyEnum::B(42);
2145        let enum_c = MyEnum::C;
2146
2147        // Create keypath for variant A
2148        let kp_a = enum_variant(
2149            |e: &MyEnum| match e {
2150                MyEnum::A(s) => Some(s),
2151                _ => None,
2152            },
2153            |e: &mut MyEnum| match e {
2154                MyEnum::A(s) => Some(s),
2155                _ => None,
2156            },
2157            |s: String| MyEnum::A(s),
2158        );
2159
2160        // Test extraction
2161        assert_eq!(kp_a.get(&enum_a), Some(&"hello".to_string()));
2162        assert_eq!(kp_a.get(&enum_b), None);
2163        assert_eq!(kp_a.get(&enum_c), None);
2164
2165        // Test embedding
2166        let embedded = kp_a.embed("world".to_string());
2167        assert_eq!(embedded, MyEnum::A("world".to_string()));
2168
2169        // Test mutable access
2170        if let Some(val) = kp_a.get_mut(&mut enum_a) {
2171            *val = "modified".to_string();
2172        }
2173        assert_eq!(enum_a, MyEnum::A("modified".to_string()));
2174    }
2175
2176    #[test]
2177    fn test_container_kp_box() {
2178        let boxed = Box::new("value".to_string());
2179        let mut boxed_mut = Box::new("original".to_string());
2180
2181        let box_kp = kp_box();
2182
2183        // Test get
2184        assert_eq!(box_kp.get(&boxed), Some(&"value".to_string()));
2185
2186        // Test get_mut
2187        if let Some(val) = box_kp.get_mut(&mut boxed_mut) {
2188            *val = "modified".to_string();
2189        }
2190        assert_eq!(*boxed_mut, "modified".to_string());
2191    }
2192
2193    #[test]
2194    fn test_container_kp_arc() {
2195        let arc = Arc::new("value".to_string());
2196        let mut arc_mut = Arc::new("original".to_string());
2197
2198        let arc_kp = kp_arc();
2199
2200        // Test get
2201        assert_eq!(arc_kp.get(&arc), Some(&"value".to_string()));
2202
2203        // Test get_mut (only works if Arc has no other references)
2204        if let Some(val) = arc_kp.get_mut(&mut arc_mut) {
2205            *val = "modified".to_string();
2206        }
2207        assert_eq!(*arc_mut, "modified".to_string());
2208
2209        // Test with multiple references (should return None for mutable access)
2210        let arc_shared = Arc::new("shared".to_string());
2211        let arc_shared2 = Arc::clone(&arc_shared);
2212        let mut arc_shared_mut = arc_shared;
2213        assert_eq!(arc_kp.get_mut(&mut arc_shared_mut), None);
2214    }
2215
2216    #[test]
2217    fn test_enum_kp_composition() {
2218        // Test composing enum keypath with other keypaths
2219        #[derive(Debug, PartialEq)]
2220        struct Inner {
2221            value: String,
2222        }
2223
2224        let result: Result<Inner, i32> = Ok(Inner {
2225            value: "nested".to_string(),
2226        });
2227
2228        // Create keypath to Inner.value
2229        let inner_kp = KpType::new(
2230            |i: &Inner| Some(&i.value),
2231            |i: &mut Inner| Some(&mut i.value),
2232        );
2233
2234        // Get the Ok keypath and convert to Kp for composition
2235        let ok_kp = enum_ok::<Inner, i32>();
2236        let ok_kp_base = ok_kp.into_kp();
2237        let composed = ok_kp_base.then(inner_kp);
2238
2239        assert_eq!(composed.get(&result), Some(&"nested".to_string()));
2240    }
2241
2242    #[test]
2243    fn test_pkp_basic() {
2244        #[derive(Debug)]
2245        struct User {
2246            name: String,
2247            age: i32,
2248        }
2249
2250        let user = User {
2251            name: "Alice".to_string(),
2252            age: 30,
2253        };
2254
2255        // Create regular keypaths
2256        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2257        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2258
2259        // Convert to partial keypaths
2260        let name_pkp = PKp::new(name_kp);
2261        let age_pkp = PKp::new(age_kp);
2262
2263        // Test get_as with correct type
2264        assert_eq!(name_pkp.get_as::<String>(&user), Some(&"Alice".to_string()));
2265        assert_eq!(age_pkp.get_as::<i32>(&user), Some(&30));
2266
2267        // Test get_as with wrong type returns None
2268        assert_eq!(name_pkp.get_as::<i32>(&user), None);
2269        assert_eq!(age_pkp.get_as::<String>(&user), None);
2270
2271        // Test value_type_id
2272        assert_eq!(name_pkp.value_type_id(), TypeId::of::<String>());
2273        assert_eq!(age_pkp.value_type_id(), TypeId::of::<i32>());
2274    }
2275
2276    #[test]
2277    fn test_pkp_collection() {
2278        #[derive(Debug)]
2279        struct User {
2280            name: String,
2281            age: i32,
2282        }
2283
2284        let user = User {
2285            name: "Bob".to_string(),
2286            age: 25,
2287        };
2288
2289        // Create a collection of partial keypaths
2290        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2291        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2292
2293        let keypaths: Vec<PKp<User>> = vec![PKp::new(name_kp), PKp::new(age_kp)];
2294
2295        // Access values through the collection
2296        let name_value = keypaths[0].get_as::<String>(&user);
2297        let age_value = keypaths[1].get_as::<i32>(&user);
2298
2299        assert_eq!(name_value, Some(&"Bob".to_string()));
2300        assert_eq!(age_value, Some(&25));
2301    }
2302
2303    #[test]
2304    fn test_pkp_for_arc() {
2305        #[derive(Debug)]
2306        struct User {
2307            name: String,
2308        }
2309
2310        let user = Arc::new(User {
2311            name: "Charlie".to_string(),
2312        });
2313
2314        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2315        let name_pkp = PKp::new(name_kp);
2316
2317        // Adapt for Arc
2318        let arc_pkp = name_pkp.for_arc();
2319
2320        assert_eq!(
2321            arc_pkp.get_as::<String>(&user),
2322            Some(&"Charlie".to_string())
2323        );
2324    }
2325
2326    #[test]
2327    fn test_pkp_for_option() {
2328        #[derive(Debug)]
2329        struct User {
2330            name: String,
2331        }
2332
2333        let some_user = Some(User {
2334            name: "Diana".to_string(),
2335        });
2336        let none_user: Option<User> = None;
2337
2338        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2339        let name_pkp = PKp::new(name_kp);
2340
2341        // Adapt for Option
2342        let opt_pkp = name_pkp.for_option();
2343
2344        assert_eq!(
2345            opt_pkp.get_as::<String>(&some_user),
2346            Some(&"Diana".to_string())
2347        );
2348        assert_eq!(opt_pkp.get_as::<String>(&none_user), None);
2349    }
2350
2351    #[test]
2352    fn test_akp_basic() {
2353        #[derive(Debug)]
2354        struct User {
2355            name: String,
2356            age: i32,
2357        }
2358
2359        #[derive(Debug)]
2360        struct Product {
2361            title: String,
2362            price: f64,
2363        }
2364
2365        let user = User {
2366            name: "Eve".to_string(),
2367            age: 28,
2368        };
2369
2370        let product = Product {
2371            title: "Book".to_string(),
2372            price: 19.99,
2373        };
2374
2375        // Create AnyKeypaths
2376        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2377        let user_name_akp = AKp::new(user_name_kp);
2378
2379        let product_title_kp = KpType::new(
2380            |p: &Product| Some(&p.title),
2381            |p: &mut Product| Some(&mut p.title),
2382        );
2383        let product_title_akp = AKp::new(product_title_kp);
2384
2385        // Test get_as with correct types
2386        assert_eq!(
2387            user_name_akp.get_as::<User, String>(&user),
2388            Some(Some(&"Eve".to_string()))
2389        );
2390        assert_eq!(
2391            product_title_akp.get_as::<Product, String>(&product),
2392            Some(Some(&"Book".to_string()))
2393        );
2394
2395        // Test get_as with wrong root type
2396        assert_eq!(user_name_akp.get_as::<Product, String>(&product), None);
2397        assert_eq!(product_title_akp.get_as::<User, String>(&user), None);
2398
2399        // Test TypeIds
2400        assert_eq!(user_name_akp.root_type_id(), TypeId::of::<User>());
2401        assert_eq!(user_name_akp.value_type_id(), TypeId::of::<String>());
2402        assert_eq!(product_title_akp.root_type_id(), TypeId::of::<Product>());
2403        assert_eq!(product_title_akp.value_type_id(), TypeId::of::<String>());
2404    }
2405
2406    #[test]
2407    fn test_akp_heterogeneous_collection() {
2408        #[derive(Debug)]
2409        struct User {
2410            name: String,
2411        }
2412
2413        #[derive(Debug)]
2414        struct Product {
2415            title: String,
2416        }
2417
2418        let user = User {
2419            name: "Frank".to_string(),
2420        };
2421        let product = Product {
2422            title: "Laptop".to_string(),
2423        };
2424
2425        // Create a heterogeneous collection of AnyKeypaths
2426        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2427        let product_title_kp = KpType::new(
2428            |p: &Product| Some(&p.title),
2429            |p: &mut Product| Some(&mut p.title),
2430        );
2431
2432        let keypaths: Vec<AKp> = vec![AKp::new(user_name_kp), AKp::new(product_title_kp)];
2433
2434        // Access through trait objects
2435        let user_any: &dyn Any = &user;
2436        let product_any: &dyn Any = &product;
2437
2438        let user_value = keypaths[0].get(user_any);
2439        let product_value = keypaths[1].get(product_any);
2440
2441        assert!(user_value.is_some());
2442        assert!(product_value.is_some());
2443
2444        // Downcast to concrete types
2445        assert_eq!(
2446            user_value.and_then(|v| v.downcast_ref::<String>()),
2447            Some(&"Frank".to_string())
2448        );
2449        assert_eq!(
2450            product_value.and_then(|v| v.downcast_ref::<String>()),
2451            Some(&"Laptop".to_string())
2452        );
2453    }
2454
2455    #[test]
2456    fn test_akp_for_option() {
2457        #[derive(Debug)]
2458        struct User {
2459            name: String,
2460        }
2461
2462        let some_user = Some(User {
2463            name: "Grace".to_string(),
2464        });
2465        let none_user: Option<User> = None;
2466
2467        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2468        let name_akp = AKp::new(name_kp);
2469
2470        // Adapt for Option
2471        let opt_akp = name_akp.for_option::<User>();
2472
2473        assert_eq!(
2474            opt_akp.get_as::<Option<User>, String>(&some_user),
2475            Some(Some(&"Grace".to_string()))
2476        );
2477        assert_eq!(
2478            opt_akp.get_as::<Option<User>, String>(&none_user),
2479            Some(None)
2480        );
2481    }
2482
2483    #[test]
2484    fn test_akp_for_result() {
2485        #[derive(Debug)]
2486        struct User {
2487            name: String,
2488        }
2489
2490        let ok_user: Result<User, String> = Ok(User {
2491            name: "Henry".to_string(),
2492        });
2493        let err_user: Result<User, String> = Err("Not found".to_string());
2494
2495        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2496        let name_akp = AKp::new(name_kp);
2497
2498        // Adapt for Result
2499        let result_akp = name_akp.for_result::<User, String>();
2500
2501        assert_eq!(
2502            result_akp.get_as::<Result<User, String>, String>(&ok_user),
2503            Some(Some(&"Henry".to_string()))
2504        );
2505        assert_eq!(
2506            result_akp.get_as::<Result<User, String>, String>(&err_user),
2507            Some(None)
2508        );
2509    }
2510
2511    // ========== MAP TESTS ==========
2512
2513    #[test]
2514    fn test_kp_map() {
2515        #[derive(Debug)]
2516        struct User {
2517            name: String,
2518            age: i32,
2519        }
2520
2521        let user = User {
2522            name: "Alice".to_string(),
2523            age: 30,
2524        };
2525
2526        // Map string to its length
2527        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2528        let len_kp = name_kp.map(|name: &String| name.len());
2529
2530        assert_eq!(len_kp.get(&user), Some(5));
2531
2532        // Map age to double
2533        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2534        let double_age_kp = age_kp.map(|age: &i32| age * 2);
2535
2536        assert_eq!(double_age_kp.get(&user), Some(60));
2537
2538        // Map to boolean
2539        let is_adult_kp = age_kp.map(|age: &i32| *age >= 18);
2540        assert_eq!(is_adult_kp.get(&user), Some(true));
2541    }
2542
2543    #[test]
2544    fn test_kp_filter() {
2545        #[derive(Debug)]
2546        struct User {
2547            name: String,
2548            age: i32,
2549        }
2550
2551        let adult = User {
2552            name: "Alice".to_string(),
2553            age: 30,
2554        };
2555
2556        let minor = User {
2557            name: "Bob".to_string(),
2558            age: 15,
2559        };
2560
2561        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2562        let adult_age_kp = age_kp.filter(|age: &i32| *age >= 18);
2563
2564        assert_eq!(adult_age_kp.get(&adult), Some(&30));
2565        assert_eq!(adult_age_kp.get(&minor), None);
2566
2567        // Filter names by length
2568        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2569        let short_name_kp = name_kp.filter(|name: &String| name.len() <= 4);
2570
2571        assert_eq!(short_name_kp.get(&minor), Some(&"Bob".to_string()));
2572        assert_eq!(short_name_kp.get(&adult), None);
2573    }
2574
2575    #[test]
2576    fn test_kp_map_and_filter() {
2577        #[derive(Debug)]
2578        struct User {
2579            scores: Vec<i32>,
2580        }
2581
2582        let user = User {
2583            scores: vec![85, 92, 78, 95],
2584        };
2585
2586        let scores_kp = KpType::new(
2587            |u: &User| Some(&u.scores),
2588            |u: &mut User| Some(&mut u.scores),
2589        );
2590
2591        // Map to average score
2592        let avg_kp =
2593            scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2594
2595        // Filter for high averages
2596        let high_avg_kp = avg_kp.filter(|avg: &i32| *avg >= 85);
2597
2598        assert_eq!(high_avg_kp.get(&user), Some(87)); // (85+92+78+95)/4 = 87.5 -> 87
2599    }
2600
2601    #[test]
2602    fn test_enum_kp_map() {
2603        let ok_result: Result<String, i32> = Ok("hello".to_string());
2604        let err_result: Result<String, i32> = Err(42);
2605
2606        let ok_kp = enum_ok::<String, i32>();
2607        let len_kp = ok_kp.map(|s: &String| s.len());
2608
2609        assert_eq!(len_kp.get(&ok_result), Some(5));
2610        assert_eq!(len_kp.get(&err_result), None);
2611
2612        // Map Option
2613        let some_opt = Some(vec![1, 2, 3, 4, 5]);
2614        let none_opt: Option<Vec<i32>> = None;
2615
2616        let some_kp = enum_some::<Vec<i32>>();
2617        let count_kp = some_kp.map(|vec: &Vec<i32>| vec.len());
2618
2619        assert_eq!(count_kp.get(&some_opt), Some(5));
2620        assert_eq!(count_kp.get(&none_opt), None);
2621    }
2622
2623    #[test]
2624    fn test_enum_kp_filter() {
2625        let ok_result1: Result<i32, String> = Ok(42);
2626        let ok_result2: Result<i32, String> = Ok(-5);
2627        let err_result: Result<i32, String> = Err("error".to_string());
2628
2629        let ok_kp = enum_ok::<i32, String>();
2630        let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
2631
2632        assert_eq!(positive_kp.get(&ok_result1), Some(&42));
2633        assert_eq!(positive_kp.get(&ok_result2), None); // Negative number filtered out
2634        assert_eq!(positive_kp.get(&err_result), None); // Err variant
2635
2636        // Filter Option strings by length
2637        let long_str = Some("hello world".to_string());
2638        let short_str = Some("hi".to_string());
2639
2640        let some_kp = enum_some::<String>();
2641        let long_kp = some_kp.filter(|s: &String| s.len() > 5);
2642
2643        assert_eq!(long_kp.get(&long_str), Some(&"hello world".to_string()));
2644        assert_eq!(long_kp.get(&short_str), None);
2645    }
2646
2647    #[test]
2648    fn test_pkp_filter() {
2649        #[derive(Debug)]
2650        struct User {
2651            name: String,
2652            age: i32,
2653        }
2654
2655        let adult = User {
2656            name: "Alice".to_string(),
2657            age: 30,
2658        };
2659
2660        let minor = User {
2661            name: "Bob".to_string(),
2662            age: 15,
2663        };
2664
2665        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2666        let age_pkp = PKp::new(age_kp);
2667
2668        // Filter for adults
2669        let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
2670
2671        assert_eq!(adult_pkp.get_as::<i32>(&adult), Some(&30));
2672        assert_eq!(adult_pkp.get_as::<i32>(&minor), None);
2673
2674        // Filter names
2675        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2676        let name_pkp = PKp::new(name_kp);
2677        let short_name_pkp = name_pkp.filter::<String, _>(|name| name.len() <= 4);
2678
2679        assert_eq!(
2680            short_name_pkp.get_as::<String>(&minor),
2681            Some(&"Bob".to_string())
2682        );
2683        assert_eq!(short_name_pkp.get_as::<String>(&adult), None);
2684    }
2685
2686    #[test]
2687    fn test_akp_filter() {
2688        #[derive(Debug)]
2689        struct User {
2690            age: i32,
2691        }
2692
2693        #[derive(Debug)]
2694        struct Product {
2695            price: f64,
2696        }
2697
2698        let adult = User { age: 30 };
2699        let minor = User { age: 15 };
2700        let expensive = Product { price: 99.99 };
2701        let cheap = Product { price: 5.0 };
2702
2703        // Filter user ages
2704        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
2705        let age_akp = AKp::new(age_kp);
2706        let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
2707
2708        assert_eq!(adult_akp.get_as::<User, i32>(&adult), Some(Some(&30)));
2709        assert_eq!(adult_akp.get_as::<User, i32>(&minor), Some(None));
2710
2711        // Filter product prices
2712        let price_kp = KpType::new(
2713            |p: &Product| Some(&p.price),
2714            |p: &mut Product| Some(&mut p.price),
2715        );
2716        let price_akp = AKp::new(price_kp);
2717        let expensive_akp = price_akp.filter::<Product, f64, _>(|price| *price > 50.0);
2718
2719        assert_eq!(
2720            expensive_akp.get_as::<Product, f64>(&expensive),
2721            Some(Some(&99.99))
2722        );
2723        assert_eq!(expensive_akp.get_as::<Product, f64>(&cheap), Some(None));
2724    }
2725
2726    // ========== ITERATOR-RELATED HOF TESTS ==========
2727
2728    #[test]
2729    fn test_kp_filter_map() {
2730        #[derive(Debug)]
2731        struct User {
2732            middle_name: Option<String>,
2733        }
2734
2735        let user_with = User {
2736            middle_name: Some("Marie".to_string()),
2737        };
2738        let user_without = User { middle_name: None };
2739
2740        let middle_kp = KpType::new(
2741            |u: &User| Some(&u.middle_name),
2742            |u: &mut User| Some(&mut u.middle_name),
2743        );
2744
2745        let first_char_kp = middle_kp
2746            .filter_map(|opt: &Option<String>| opt.as_ref().and_then(|s| s.chars().next()));
2747
2748        assert_eq!(first_char_kp.get(&user_with), Some('M'));
2749        assert_eq!(first_char_kp.get(&user_without), None);
2750    }
2751
2752    #[test]
2753    fn test_kp_inspect() {
2754        #[derive(Debug)]
2755        struct User {
2756            name: String,
2757        }
2758
2759        let user = User {
2760            name: "Alice".to_string(),
2761        };
2762
2763        // Simple test - just verify that inspect returns the correct value
2764        // and can perform side effects
2765
2766        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
2767
2768        // We can't easily test side effects with Copy constraint,
2769        // so we'll just test that inspect passes through the value
2770        let result = name_kp.get(&user);
2771        assert_eq!(result, Some(&"Alice".to_string()));
2772
2773        // The inspect method works, it just requires Copy closures
2774        // which limits its usefulness for complex side effects
2775    }
2776
2777    #[test]
2778    fn test_kp_fold_value() {
2779        #[derive(Debug)]
2780        struct User {
2781            scores: Vec<i32>,
2782        }
2783
2784        let user = User {
2785            scores: vec![85, 92, 78, 95],
2786        };
2787
2788        let scores_kp = KpType::new(
2789            |u: &User| Some(&u.scores),
2790            |u: &mut User| Some(&mut u.scores),
2791        );
2792
2793        // Sum all scores
2794        let sum_fn =
2795            scores_kp.fold_value(0, |acc, scores: &Vec<i32>| scores.iter().sum::<i32>() + acc);
2796
2797        assert_eq!(sum_fn(&user), 350);
2798    }
2799
2800    #[test]
2801    fn test_kp_any_all() {
2802        #[derive(Debug)]
2803        struct User {
2804            scores: Vec<i32>,
2805        }
2806
2807        let user_high = User {
2808            scores: vec![85, 92, 88],
2809        };
2810        let user_mixed = User {
2811            scores: vec![65, 92, 78],
2812        };
2813
2814        let scores_kp = KpType::new(
2815            |u: &User| Some(&u.scores),
2816            |u: &mut User| Some(&mut u.scores),
2817        );
2818
2819        // Test any
2820        let has_high_fn = scores_kp.any(|scores: &Vec<i32>| scores.iter().any(|&s| s > 90));
2821        assert!(has_high_fn(&user_high));
2822        assert!(has_high_fn(&user_mixed));
2823
2824        // Test all
2825        let all_passing_fn = scores_kp.all(|scores: &Vec<i32>| scores.iter().all(|&s| s >= 80));
2826        assert!(all_passing_fn(&user_high));
2827        assert!(!all_passing_fn(&user_mixed));
2828    }
2829
2830    #[test]
2831    fn test_kp_count_items() {
2832        #[derive(Debug)]
2833        struct User {
2834            tags: Vec<String>,
2835        }
2836
2837        let user = User {
2838            tags: vec!["rust".to_string(), "web".to_string(), "backend".to_string()],
2839        };
2840
2841        let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2842        let count_fn = tags_kp.count_items(|tags: &Vec<String>| tags.len());
2843
2844        assert_eq!(count_fn(&user), Some(3));
2845    }
2846
2847    #[test]
2848    fn test_kp_find_in() {
2849        #[derive(Debug)]
2850        struct User {
2851            scores: Vec<i32>,
2852        }
2853
2854        let user = User {
2855            scores: vec![85, 92, 78, 95, 88],
2856        };
2857
2858        let scores_kp = KpType::new(
2859            |u: &User| Some(&u.scores),
2860            |u: &mut User| Some(&mut u.scores),
2861        );
2862
2863        // Find first score > 90
2864        let first_high_fn =
2865            scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 90).copied());
2866
2867        assert_eq!(first_high_fn(&user), Some(92));
2868
2869        // Find score > 100 (doesn't exist)
2870        let perfect_fn =
2871            scores_kp.find_in(|scores: &Vec<i32>| scores.iter().find(|&&s| s > 100).copied());
2872
2873        assert_eq!(perfect_fn(&user), None);
2874    }
2875
2876    #[test]
2877    fn test_kp_take_skip() {
2878        #[derive(Debug)]
2879        struct User {
2880            tags: Vec<String>,
2881        }
2882
2883        let user = User {
2884            tags: vec![
2885                "a".to_string(),
2886                "b".to_string(),
2887                "c".to_string(),
2888                "d".to_string(),
2889            ],
2890        };
2891
2892        let tags_kp = KpType::new(|u: &User| Some(&u.tags), |u: &mut User| Some(&mut u.tags));
2893
2894        // Take first 2
2895        let take_fn = tags_kp.take(2, |tags: &Vec<String>, n| {
2896            tags.iter().take(n).cloned().collect::<Vec<_>>()
2897        });
2898
2899        let taken = take_fn(&user).unwrap();
2900        assert_eq!(taken, vec!["a".to_string(), "b".to_string()]);
2901
2902        // Skip first 2
2903        let skip_fn = tags_kp.skip(2, |tags: &Vec<String>, n| {
2904            tags.iter().skip(n).cloned().collect::<Vec<_>>()
2905        });
2906
2907        let skipped = skip_fn(&user).unwrap();
2908        assert_eq!(skipped, vec!["c".to_string(), "d".to_string()]);
2909    }
2910
2911    #[test]
2912    fn test_kp_partition() {
2913        #[derive(Debug)]
2914        struct User {
2915            scores: Vec<i32>,
2916        }
2917
2918        let user = User {
2919            scores: vec![85, 92, 65, 95, 72, 58],
2920        };
2921
2922        let scores_kp = KpType::new(
2923            |u: &User| Some(&u.scores),
2924            |u: &mut User| Some(&mut u.scores),
2925        );
2926
2927        let partition_fn = scores_kp.partition_value(|scores: &Vec<i32>| -> (Vec<i32>, Vec<i32>) {
2928            scores.iter().copied().partition(|&s| s >= 70)
2929        });
2930
2931        let (passing, failing) = partition_fn(&user).unwrap();
2932        assert_eq!(passing, vec![85, 92, 95, 72]);
2933        assert_eq!(failing, vec![65, 58]);
2934    }
2935
2936    #[test]
2937    fn test_kp_min_max() {
2938        #[derive(Debug)]
2939        struct User {
2940            scores: Vec<i32>,
2941        }
2942
2943        let user = User {
2944            scores: vec![85, 92, 78, 95, 88],
2945        };
2946
2947        let scores_kp = KpType::new(
2948            |u: &User| Some(&u.scores),
2949            |u: &mut User| Some(&mut u.scores),
2950        );
2951
2952        // Min
2953        let min_fn = scores_kp.min_value(|scores: &Vec<i32>| scores.iter().min().copied());
2954        assert_eq!(min_fn(&user), Some(78));
2955
2956        // Max
2957        let max_fn = scores_kp.max_value(|scores: &Vec<i32>| scores.iter().max().copied());
2958        assert_eq!(max_fn(&user), Some(95));
2959    }
2960
2961    #[test]
2962    fn test_kp_sum() {
2963        #[derive(Debug)]
2964        struct User {
2965            scores: Vec<i32>,
2966        }
2967
2968        let user = User {
2969            scores: vec![85, 92, 78],
2970        };
2971
2972        let scores_kp = KpType::new(
2973            |u: &User| Some(&u.scores),
2974            |u: &mut User| Some(&mut u.scores),
2975        );
2976
2977        let sum_fn = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum::<i32>());
2978        assert_eq!(sum_fn(&user), Some(255));
2979
2980        // Average
2981        let avg_fn =
2982            scores_kp.map(|scores: &Vec<i32>| scores.iter().sum::<i32>() / scores.len() as i32);
2983        assert_eq!(avg_fn.get(&user), Some(85));
2984    }
2985
2986    #[test]
2987    fn test_kp_chain() {
2988        #[derive(Debug)]
2989        struct User {
2990            profile: Profile,
2991        }
2992
2993        #[derive(Debug)]
2994        struct Profile {
2995            settings: Settings,
2996        }
2997
2998        #[derive(Debug)]
2999        struct Settings {
3000            theme: String,
3001        }
3002
3003        let user = User {
3004            profile: Profile {
3005                settings: Settings {
3006                    theme: "dark".to_string(),
3007                },
3008            },
3009        };
3010
3011        let profile_kp = KpType::new(
3012            |u: &User| Some(&u.profile),
3013            |u: &mut User| Some(&mut u.profile),
3014        );
3015        let settings_kp = KpType::new(
3016            |p: &Profile| Some(&p.settings),
3017            |p: &mut Profile| Some(&mut p.settings),
3018        );
3019        let theme_kp = KpType::new(
3020            |s: &Settings| Some(&s.theme),
3021            |s: &mut Settings| Some(&mut s.theme),
3022        );
3023
3024        // Chain all together - store intermediate result
3025        let profile_settings = profile_kp.chain(settings_kp);
3026        let theme_path = profile_settings.chain(theme_kp);
3027        assert_eq!(theme_path.get(&user), Some(&"dark".to_string()));
3028    }
3029
3030    #[test]
3031    fn test_kp_zip() {
3032        #[derive(Debug)]
3033        struct User {
3034            name: String,
3035            age: i32,
3036        }
3037
3038        let user = User {
3039            name: "Alice".to_string(),
3040            age: 30,
3041        };
3042
3043        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3044        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3045
3046        let zipped_fn = zip_kps(&name_kp, &age_kp);
3047        let result = zipped_fn(&user);
3048
3049        assert_eq!(result, Some((&"Alice".to_string(), &30)));
3050    }
3051
3052    #[test]
3053    fn test_kp_complex_pipeline() {
3054        #[derive(Debug)]
3055        struct User {
3056            transactions: Vec<Transaction>,
3057        }
3058
3059        #[derive(Debug)]
3060        struct Transaction {
3061            amount: f64,
3062            category: String,
3063        }
3064
3065        let user = User {
3066            transactions: vec![
3067                Transaction {
3068                    amount: 50.0,
3069                    category: "food".to_string(),
3070                },
3071                Transaction {
3072                    amount: 100.0,
3073                    category: "transport".to_string(),
3074                },
3075                Transaction {
3076                    amount: 25.0,
3077                    category: "food".to_string(),
3078                },
3079                Transaction {
3080                    amount: 200.0,
3081                    category: "shopping".to_string(),
3082                },
3083            ],
3084        };
3085
3086        let txns_kp = KpType::new(
3087            |u: &User| Some(&u.transactions),
3088            |u: &mut User| Some(&mut u.transactions),
3089        );
3090
3091        // Calculate total food expenses
3092        let food_total = txns_kp.map(|txns: &Vec<Transaction>| {
3093            txns.iter()
3094                .filter(|t| t.category == "food")
3095                .map(|t| t.amount)
3096                .sum::<f64>()
3097        });
3098
3099        assert_eq!(food_total.get(&user), Some(75.0));
3100
3101        // Check if any transaction is over 150
3102        let has_large =
3103            txns_kp.any(|txns: &Vec<Transaction>| txns.iter().any(|t| t.amount > 150.0));
3104
3105        assert!(has_large(&user));
3106
3107        // Count transactions
3108        let count = txns_kp.count_items(|txns: &Vec<Transaction>| txns.len());
3109        assert_eq!(count(&user), Some(4));
3110    }
3111
3112    // ========== COPY AND 'STATIC TRAIT BOUND TESTS ==========
3113    // These tests verify that Copy and 'static bounds don't cause cloning or memory leaks
3114
3115    #[test]
3116    fn test_no_clone_required_for_root() {
3117        use std::sync::Arc;
3118        use std::sync::atomic::{AtomicUsize, Ordering};
3119
3120        // Create a type that is NOT Clone and NOT Copy
3121        // If operations clone unnecessarily, this will fail to compile
3122        struct NonCloneableRoot {
3123            data: Arc<AtomicUsize>,
3124            cached_value: usize,
3125        }
3126
3127        impl NonCloneableRoot {
3128            fn new() -> Self {
3129                Self {
3130                    data: Arc::new(AtomicUsize::new(42)),
3131                    cached_value: 42,
3132                }
3133            }
3134
3135            fn increment(&mut self) {
3136                self.data.fetch_add(1, Ordering::SeqCst);
3137                self.cached_value = self.data.load(Ordering::SeqCst);
3138            }
3139
3140            fn get_value(&self) -> &usize {
3141                &self.cached_value
3142            }
3143
3144            fn get_value_mut(&mut self) -> &mut usize {
3145                &mut self.cached_value
3146            }
3147        }
3148
3149        let mut root = NonCloneableRoot::new();
3150
3151        // Create a keypath - this works because we only need &Root, not Clone
3152        let data_kp = KpType::new(
3153            |r: &NonCloneableRoot| Some(r.get_value()),
3154            |r: &mut NonCloneableRoot| {
3155                r.increment();
3156                Some(r.get_value_mut())
3157            },
3158        );
3159
3160        // Test that we can use the keypath without cloning
3161        assert_eq!(data_kp.get(&root), Some(&42));
3162
3163        {
3164            // Test map - no cloning of root happens
3165            let doubled = data_kp.map(|val: &usize| val * 2);
3166            assert_eq!(doubled.get(&root), Some(84));
3167
3168            // Test filter - no cloning of root happens
3169            let filtered = data_kp.filter(|val: &usize| *val > 0);
3170            assert_eq!(filtered.get(&root), Some(&42));
3171        } // Drop derived keypaths
3172
3173        // Test mutable access - no cloning happens
3174        let value_ref = data_kp.get_mut(&mut root);
3175        assert!(value_ref.is_some());
3176    }
3177
3178    #[test]
3179    fn test_no_clone_required_for_value() {
3180        use std::sync::Arc;
3181        use std::sync::atomic::{AtomicUsize, Ordering};
3182
3183        // Value type that is NOT Clone and NOT Copy
3184        struct NonCloneableValue {
3185            counter: Arc<AtomicUsize>,
3186        }
3187
3188        impl NonCloneableValue {
3189            fn new(val: usize) -> Self {
3190                Self {
3191                    counter: Arc::new(AtomicUsize::new(val)),
3192                }
3193            }
3194
3195            fn get(&self) -> usize {
3196                self.counter.load(Ordering::SeqCst)
3197            }
3198        }
3199
3200        struct Root {
3201            value: NonCloneableValue,
3202        }
3203
3204        let root = Root {
3205            value: NonCloneableValue::new(100),
3206        };
3207
3208        // Keypath that returns reference to non-cloneable value
3209        let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3210
3211        // Map to extract the counter value - no cloning happens
3212        let counter_kp = value_kp.map(|v: &NonCloneableValue| v.get());
3213        assert_eq!(counter_kp.get(&root), Some(100));
3214
3215        // Filter non-cloneable values - no cloning happens
3216        let filtered = value_kp.filter(|v: &NonCloneableValue| v.get() >= 50);
3217        assert!(filtered.get(&root).is_some());
3218    }
3219
3220    #[test]
3221    fn test_static_does_not_leak_memory() {
3222        use std::sync::Arc;
3223        use std::sync::atomic::{AtomicUsize, Ordering};
3224
3225        // Track number of instances created and dropped
3226        static CREATED: AtomicUsize = AtomicUsize::new(0);
3227        static DROPPED: AtomicUsize = AtomicUsize::new(0);
3228
3229        struct Tracked {
3230            id: usize,
3231        }
3232
3233        impl Tracked {
3234            fn new() -> Self {
3235                let id = CREATED.fetch_add(1, Ordering::SeqCst);
3236                Self { id }
3237            }
3238        }
3239
3240        impl Drop for Tracked {
3241            fn drop(&mut self) {
3242                DROPPED.fetch_add(1, Ordering::SeqCst);
3243            }
3244        }
3245
3246        struct Root {
3247            data: Tracked,
3248        }
3249
3250        // Reset counters
3251        CREATED.store(0, Ordering::SeqCst);
3252        DROPPED.store(0, Ordering::SeqCst);
3253
3254        {
3255            let root = Root {
3256                data: Tracked::new(),
3257            };
3258
3259            let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3260
3261            // Use map multiple times
3262            let mapped1 = data_kp.map(|t: &Tracked| t.id);
3263            let mapped2 = data_kp.map(|t: &Tracked| t.id + 1);
3264            let mapped3 = data_kp.map(|t: &Tracked| t.id + 2);
3265
3266            assert_eq!(mapped1.get(&root), Some(0));
3267            assert_eq!(mapped2.get(&root), Some(1));
3268            assert_eq!(mapped3.get(&root), Some(2));
3269
3270            // Only 1 instance should be created (the one in root)
3271            assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3272            assert_eq!(DROPPED.load(Ordering::SeqCst), 0);
3273        }
3274
3275        // After root is dropped, exactly 1 drop should happen
3276        assert_eq!(CREATED.load(Ordering::SeqCst), 1);
3277        assert_eq!(DROPPED.load(Ordering::SeqCst), 1);
3278
3279        // No memory leaks - created == dropped
3280    }
3281
3282    #[test]
3283    fn test_references_not_cloned() {
3284        use std::sync::Arc;
3285
3286        // Large data structure that would be expensive to clone
3287        struct ExpensiveData {
3288            large_vec: Vec<u8>,
3289        }
3290
3291        impl ExpensiveData {
3292            fn new(size: usize) -> Self {
3293                Self {
3294                    large_vec: vec![0u8; size],
3295                }
3296            }
3297
3298            fn size(&self) -> usize {
3299                self.large_vec.len()
3300            }
3301        }
3302
3303        struct Root {
3304            expensive: ExpensiveData,
3305        }
3306
3307        let root = Root {
3308            expensive: ExpensiveData::new(1_000_000), // 1MB
3309        };
3310
3311        let expensive_kp = KpType::new(
3312            |r: &Root| Some(&r.expensive),
3313            |r: &mut Root| Some(&mut r.expensive),
3314        );
3315
3316        // Map operations work with references - no cloning of ExpensiveData
3317        let size_kp = expensive_kp.map(|e: &ExpensiveData| e.size());
3318        assert_eq!(size_kp.get(&root), Some(1_000_000));
3319
3320        // Filter also works with references - no cloning
3321        let large_filter = expensive_kp.filter(|e: &ExpensiveData| e.size() > 500_000);
3322        assert!(large_filter.get(&root).is_some());
3323
3324        // All operations work through references - no expensive clones happen
3325    }
3326
3327    #[test]
3328    fn test_hof_with_arc_no_extra_clones() {
3329        use std::sync::Arc;
3330
3331        #[derive(Debug)]
3332        struct SharedData {
3333            value: String,
3334        }
3335
3336        struct Root {
3337            shared: Arc<SharedData>,
3338        }
3339
3340        let shared = Arc::new(SharedData {
3341            value: "shared".to_string(),
3342        });
3343
3344        // Check initial reference count
3345        assert_eq!(Arc::strong_count(&shared), 1);
3346
3347        {
3348            let root = Root {
3349                shared: Arc::clone(&shared),
3350            };
3351
3352            // Reference count is now 2
3353            assert_eq!(Arc::strong_count(&shared), 2);
3354
3355            let shared_kp = KpType::new(
3356                |r: &Root| Some(&r.shared),
3357                |r: &mut Root| Some(&mut r.shared),
3358            );
3359
3360            // Map operation - should not increase Arc refcount
3361            let value_kp = shared_kp.map(|arc: &Arc<SharedData>| arc.value.len());
3362
3363            // Using the keypath doesn't increase refcount
3364            assert_eq!(value_kp.get(&root), Some(6));
3365            assert_eq!(Arc::strong_count(&shared), 2); // Still just 2
3366
3367            // Filter operation - should not increase Arc refcount
3368            let filtered = shared_kp.filter(|arc: &Arc<SharedData>| !arc.value.is_empty());
3369            assert!(filtered.get(&root).is_some());
3370            assert_eq!(Arc::strong_count(&shared), 2); // Still just 2
3371        } // root is dropped here
3372
3373        assert_eq!(Arc::strong_count(&shared), 1); // Back to 1
3374    }
3375
3376    #[test]
3377    fn test_closure_captures_not_root_values() {
3378        use std::sync::Arc;
3379        use std::sync::atomic::{AtomicUsize, Ordering};
3380
3381        // Track how many times the closure is called
3382        let call_count = Arc::new(AtomicUsize::new(0));
3383        let call_count_clone = Arc::clone(&call_count);
3384
3385        struct Root {
3386            value: i32,
3387        }
3388
3389        let root = Root { value: 42 };
3390
3391        let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3392
3393        // Use fold_value which doesn't require Copy (optimized HOF)
3394        // The closure captures call_count (via move), not the root or value
3395        let doubled = value_kp.fold_value(0, move |_acc, v: &i32| {
3396            call_count_clone.fetch_add(1, Ordering::SeqCst);
3397            v * 2
3398        });
3399
3400        // Call multiple times
3401        assert_eq!(doubled(&root), 84);
3402        assert_eq!(doubled(&root), 84);
3403        assert_eq!(doubled(&root), 84);
3404
3405        // Closure was called 3 times
3406        assert_eq!(call_count.load(Ordering::SeqCst), 3);
3407
3408        // The Root and value were NOT cloned - only references were passed
3409    }
3410
3411    #[test]
3412    fn test_static_with_borrowed_data() {
3413        // 'static doesn't mean the data lives forever
3414        // It means the TYPE doesn't contain non-'static references
3415
3416        struct Root {
3417            data: String,
3418        }
3419
3420        {
3421            let root = Root {
3422                data: "temporary".to_string(),
3423            };
3424
3425            let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3426
3427            // Map with 'static bound - but root is NOT static
3428            let len_kp = data_kp.map(|s: &String| s.len());
3429            assert_eq!(len_kp.get(&root), Some(9));
3430
3431            // When root goes out of scope here, everything is properly dropped
3432        } // root is dropped here along with len_kp
3433
3434        // No memory leak - root was dropped normally
3435    }
3436
3437    #[test]
3438    fn test_multiple_hof_operations_no_accumulation() {
3439        use std::sync::Arc;
3440        use std::sync::atomic::{AtomicUsize, Ordering};
3441
3442        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3443
3444        struct Tracked {
3445            id: usize,
3446        }
3447
3448        impl Drop for Tracked {
3449            fn drop(&mut self) {
3450                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3451            }
3452        }
3453
3454        struct Root {
3455            values: Vec<Tracked>,
3456        }
3457
3458        DROP_COUNT.store(0, Ordering::SeqCst);
3459
3460        {
3461            let root = Root {
3462                values: vec![Tracked { id: 1 }, Tracked { id: 2 }, Tracked { id: 3 }],
3463            };
3464
3465            let values_kp = KpType::new(
3466                |r: &Root| Some(&r.values),
3467                |r: &mut Root| Some(&mut r.values),
3468            );
3469
3470            // Multiple HOF operations - should not clone the Vec<Tracked>
3471            let count = values_kp.count_items(|v| v.len());
3472            let sum = values_kp.sum_value(|v| v.iter().map(|t| t.id).sum::<usize>());
3473            let has_2 = values_kp.any(|v| v.iter().any(|t| t.id == 2));
3474            let all_positive = values_kp.all(|v| v.iter().all(|t| t.id > 0));
3475
3476            assert_eq!(count(&root), Some(3));
3477            assert_eq!(sum(&root), Some(6));
3478            assert!(has_2(&root));
3479            assert!(all_positive(&root));
3480
3481            // No drops yet - values are still in root
3482            assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3483        }
3484
3485        // Now exactly 3 Tracked instances should be dropped
3486        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3);
3487    }
3488
3489    #[test]
3490    fn test_copy_bound_only_for_function_not_data() {
3491        // This test verifies that F: Copy means the FUNCTION must be Copy,
3492        // not the data being processed
3493
3494        #[derive(Debug)]
3495        struct NonCopyData {
3496            value: String,
3497        }
3498
3499        struct Root {
3500            data: NonCopyData,
3501        }
3502
3503        let root = Root {
3504            data: NonCopyData {
3505                value: "test".to_string(),
3506            },
3507        };
3508
3509        let data_kp = KpType::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3510
3511        // Map works even though NonCopyData is not Copy
3512        // The function pointer IS Copy, but the data is not
3513        let len_kp = data_kp.map(|d: &NonCopyData| d.value.len());
3514        assert_eq!(len_kp.get(&root), Some(4));
3515
3516        // Filter also works with non-Copy data
3517        let filtered = data_kp.filter(|d: &NonCopyData| !d.value.is_empty());
3518        assert!(filtered.get(&root).is_some());
3519    }
3520
3521    #[test]
3522    fn test_no_memory_leak_with_cyclic_references() {
3523        use std::sync::atomic::{AtomicUsize, Ordering};
3524        use std::sync::{Arc, Weak};
3525
3526        static DROP_COUNT: AtomicUsize = AtomicUsize::new(0);
3527
3528        struct Node {
3529            id: usize,
3530            parent: Option<Weak<Node>>,
3531        }
3532
3533        impl Drop for Node {
3534            fn drop(&mut self) {
3535                DROP_COUNT.fetch_add(1, Ordering::SeqCst);
3536            }
3537        }
3538
3539        struct Root {
3540            node: Arc<Node>,
3541        }
3542
3543        DROP_COUNT.store(0, Ordering::SeqCst);
3544
3545        {
3546            let root = Root {
3547                node: Arc::new(Node {
3548                    id: 1,
3549                    parent: None,
3550                }),
3551            };
3552
3553            let node_kp = KpType::new(|r: &Root| Some(&r.node), |r: &mut Root| Some(&mut r.node));
3554
3555            // Map operations don't create extra Arc clones
3556            let id_kp = node_kp.map(|n: &Arc<Node>| n.id);
3557            assert_eq!(id_kp.get(&root), Some(1));
3558
3559            // Strong count should still be 1 (only in root)
3560            assert_eq!(Arc::strong_count(&root.node), 1);
3561
3562            // No drops yet
3563            assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 0);
3564        }
3565
3566        // Exactly 1 Node should be dropped
3567        assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1);
3568    }
3569
3570    #[test]
3571    fn test_hof_operations_are_zero_cost_abstractions() {
3572        // This test verifies that HOF operations don't add overhead
3573        // by checking that the same number of operations occur
3574
3575        struct Root {
3576            value: i32,
3577        }
3578
3579        let root = Root { value: 10 };
3580
3581        let value_kp = KpType::new(|r: &Root| Some(&r.value), |r: &mut Root| Some(&mut r.value));
3582
3583        // Direct access
3584        let direct_result = value_kp.get(&root).map(|v| v * 2);
3585        assert_eq!(direct_result, Some(20));
3586
3587        // Through map HOF
3588        let mapped_kp = value_kp.map(|v: &i32| v * 2);
3589        let hof_result = mapped_kp.get(&root);
3590        assert_eq!(hof_result, Some(20));
3591
3592        // Results are identical - no extra allocations or operations
3593        assert_eq!(direct_result, hof_result);
3594    }
3595
3596    #[test]
3597    fn test_complex_closure_captures_allowed() {
3598        use std::sync::Arc;
3599
3600        // With Copy removed from many HOFs, we can now capture complex state
3601        struct Root {
3602            scores: Vec<i32>,
3603        }
3604
3605        let root = Root {
3606            scores: vec![85, 92, 78, 95, 88],
3607        };
3608
3609        let scores_kp = KpType::new(
3610            |r: &Root| Some(&r.scores),
3611            |r: &mut Root| Some(&mut r.scores),
3612        );
3613
3614        // Capture external state in HOF (only works because Copy was removed)
3615        let threshold = 90;
3616        let multiplier = Arc::new(2);
3617
3618        // These closures capture state but don't need Copy
3619        let high_scores_doubled = scores_kp.fold_value(0, move |acc, scores| {
3620            let high: i32 = scores
3621                .iter()
3622                .filter(|&&s| s >= threshold)
3623                .map(|&s| s * *multiplier)
3624                .sum();
3625            acc + high
3626        });
3627
3628        // (92 * 2) + (95 * 2) = 184 + 190 = 374
3629        assert_eq!(high_scores_doubled(&root), 374);
3630    }
3631
3632    // ========== TYPE FILTERING TESTS FOR PKP AND AKP ==========
3633    // These tests demonstrate filtering collections by TypeId
3634
3635    #[test]
3636    fn test_pkp_filter_by_value_type() {
3637        use std::any::TypeId;
3638
3639        #[derive(Debug)]
3640        struct User {
3641            name: String,
3642            age: i32,
3643            score: f64,
3644            active: bool,
3645        }
3646
3647        let user = User {
3648            name: "Alice".to_string(),
3649            age: 30,
3650            score: 95.5,
3651            active: true,
3652        };
3653
3654        // Create keypaths for different fields with different types
3655        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3656        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3657        let score_kp = KpType::new(|u: &User| Some(&u.score), |u: &mut User| Some(&mut u.score));
3658        let active_kp = KpType::new(
3659            |u: &User| Some(&u.active),
3660            |u: &mut User| Some(&mut u.active),
3661        );
3662
3663        // Convert to partial keypaths and store in a heterogeneous collection
3664        let all_keypaths: Vec<PKp<User>> = vec![
3665            PKp::new(name_kp),
3666            PKp::new(age_kp),
3667            PKp::new(score_kp),
3668            PKp::new(active_kp),
3669        ];
3670
3671        // Filter for String types
3672        let string_kps: Vec<_> = all_keypaths
3673            .iter()
3674            .filter(|pkp| pkp.value_type_id() == TypeId::of::<String>())
3675            .collect();
3676
3677        assert_eq!(string_kps.len(), 1);
3678        assert_eq!(
3679            string_kps[0].get_as::<String>(&user),
3680            Some(&"Alice".to_string())
3681        );
3682
3683        // Filter for i32 types
3684        let i32_kps: Vec<_> = all_keypaths
3685            .iter()
3686            .filter(|pkp| pkp.value_type_id() == TypeId::of::<i32>())
3687            .collect();
3688
3689        assert_eq!(i32_kps.len(), 1);
3690        assert_eq!(i32_kps[0].get_as::<i32>(&user), Some(&30));
3691
3692        // Filter for f64 types
3693        let f64_kps: Vec<_> = all_keypaths
3694            .iter()
3695            .filter(|pkp| pkp.value_type_id() == TypeId::of::<f64>())
3696            .collect();
3697
3698        assert_eq!(f64_kps.len(), 1);
3699        assert_eq!(f64_kps[0].get_as::<f64>(&user), Some(&95.5));
3700
3701        // Filter for bool types
3702        let bool_kps: Vec<_> = all_keypaths
3703            .iter()
3704            .filter(|pkp| pkp.value_type_id() == TypeId::of::<bool>())
3705            .collect();
3706
3707        assert_eq!(bool_kps.len(), 1);
3708        assert_eq!(bool_kps[0].get_as::<bool>(&user), Some(&true));
3709    }
3710
3711    #[test]
3712    fn test_pkp_filter_by_struct_type() {
3713        use std::any::TypeId;
3714
3715        #[derive(Debug, PartialEq)]
3716        struct Address {
3717            street: String,
3718            city: String,
3719        }
3720
3721        #[derive(Debug)]
3722        struct User {
3723            name: String,
3724            age: i32,
3725            address: Address,
3726        }
3727
3728        let user = User {
3729            name: "Bob".to_string(),
3730            age: 25,
3731            address: Address {
3732                street: "123 Main St".to_string(),
3733                city: "NYC".to_string(),
3734            },
3735        };
3736
3737        // Create keypaths for different types
3738        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3739        let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3740        let address_kp = KpType::new(
3741            |u: &User| Some(&u.address),
3742            |u: &mut User| Some(&mut u.address),
3743        );
3744
3745        let all_keypaths: Vec<PKp<User>> =
3746            vec![PKp::new(name_kp), PKp::new(age_kp), PKp::new(address_kp)];
3747
3748        // Filter for custom struct type (Address)
3749        let struct_kps: Vec<_> = all_keypaths
3750            .iter()
3751            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Address>())
3752            .collect();
3753
3754        assert_eq!(struct_kps.len(), 1);
3755        assert_eq!(
3756            struct_kps[0].get_as::<Address>(&user),
3757            Some(&Address {
3758                street: "123 Main St".to_string(),
3759                city: "NYC".to_string(),
3760            })
3761        );
3762
3763        // Filter for primitive types (non-struct)
3764        let primitive_kps: Vec<_> = all_keypaths
3765            .iter()
3766            .filter(|pkp| {
3767                pkp.value_type_id() == TypeId::of::<String>()
3768                    || pkp.value_type_id() == TypeId::of::<i32>()
3769            })
3770            .collect();
3771
3772        assert_eq!(primitive_kps.len(), 2);
3773    }
3774
3775    #[test]
3776    fn test_pkp_filter_by_arc_type() {
3777        use std::any::TypeId;
3778        use std::sync::Arc;
3779
3780        #[derive(Debug)]
3781        struct User {
3782            name: String,
3783            shared_data: Arc<String>,
3784            shared_number: Arc<i32>,
3785        }
3786
3787        let user = User {
3788            name: "Charlie".to_string(),
3789            shared_data: Arc::new("shared".to_string()),
3790            shared_number: Arc::new(42),
3791        };
3792
3793        // Create keypaths for different types including Arc
3794        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3795        let shared_data_kp = KpType::new(
3796            |u: &User| Some(&u.shared_data),
3797            |u: &mut User| Some(&mut u.shared_data),
3798        );
3799        let shared_number_kp = KpType::new(
3800            |u: &User| Some(&u.shared_number),
3801            |u: &mut User| Some(&mut u.shared_number),
3802        );
3803
3804        let all_keypaths: Vec<PKp<User>> = vec![
3805            PKp::new(name_kp),
3806            PKp::new(shared_data_kp),
3807            PKp::new(shared_number_kp),
3808        ];
3809
3810        // Filter for Arc<String> types
3811        let arc_string_kps: Vec<_> = all_keypaths
3812            .iter()
3813            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<String>>())
3814            .collect();
3815
3816        assert_eq!(arc_string_kps.len(), 1);
3817        assert_eq!(
3818            arc_string_kps[0]
3819                .get_as::<Arc<String>>(&user)
3820                .map(|arc| arc.as_str()),
3821            Some("shared")
3822        );
3823
3824        // Filter for Arc<i32> types
3825        let arc_i32_kps: Vec<_> = all_keypaths
3826            .iter()
3827            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Arc<i32>>())
3828            .collect();
3829
3830        assert_eq!(arc_i32_kps.len(), 1);
3831        assert_eq!(
3832            arc_i32_kps[0].get_as::<Arc<i32>>(&user).map(|arc| **arc),
3833            Some(42)
3834        );
3835
3836        // Filter for all Arc types (any T)
3837        let all_arc_kps: Vec<_> = all_keypaths
3838            .iter()
3839            .filter(|pkp| {
3840                pkp.value_type_id() == TypeId::of::<Arc<String>>()
3841                    || pkp.value_type_id() == TypeId::of::<Arc<i32>>()
3842            })
3843            .collect();
3844
3845        assert_eq!(all_arc_kps.len(), 2);
3846    }
3847
3848    #[test]
3849    fn test_pkp_filter_by_box_type() {
3850        use std::any::TypeId;
3851
3852        #[derive(Debug)]
3853        struct User {
3854            name: String,
3855            boxed_value: Box<i32>,
3856            boxed_string: Box<String>,
3857        }
3858
3859        let user = User {
3860            name: "Diana".to_string(),
3861            boxed_value: Box::new(100),
3862            boxed_string: Box::new("boxed".to_string()),
3863        };
3864
3865        // Create keypaths
3866        let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3867        let boxed_value_kp = KpType::new(
3868            |u: &User| Some(&u.boxed_value),
3869            |u: &mut User| Some(&mut u.boxed_value),
3870        );
3871        let boxed_string_kp = KpType::new(
3872            |u: &User| Some(&u.boxed_string),
3873            |u: &mut User| Some(&mut u.boxed_string),
3874        );
3875
3876        let all_keypaths: Vec<PKp<User>> = vec![
3877            PKp::new(name_kp),
3878            PKp::new(boxed_value_kp),
3879            PKp::new(boxed_string_kp),
3880        ];
3881
3882        // Filter for Box<i32>
3883        let box_i32_kps: Vec<_> = all_keypaths
3884            .iter()
3885            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<i32>>())
3886            .collect();
3887
3888        assert_eq!(box_i32_kps.len(), 1);
3889        assert_eq!(
3890            box_i32_kps[0].get_as::<Box<i32>>(&user).map(|b| **b),
3891            Some(100)
3892        );
3893
3894        // Filter for Box<String>
3895        let box_string_kps: Vec<_> = all_keypaths
3896            .iter()
3897            .filter(|pkp| pkp.value_type_id() == TypeId::of::<Box<String>>())
3898            .collect();
3899
3900        assert_eq!(box_string_kps.len(), 1);
3901        assert_eq!(
3902            box_string_kps[0]
3903                .get_as::<Box<String>>(&user)
3904                .map(|b| b.as_str()),
3905            Some("boxed")
3906        );
3907    }
3908
3909    #[test]
3910    fn test_akp_filter_by_root_and_value_type() {
3911        use std::any::TypeId;
3912
3913        #[derive(Debug)]
3914        struct User {
3915            name: String,
3916            age: i32,
3917        }
3918
3919        #[derive(Debug)]
3920        struct Product {
3921            title: String,
3922            price: f64,
3923        }
3924
3925        let user = User {
3926            name: "Eve".to_string(),
3927            age: 28,
3928        };
3929
3930        let product = Product {
3931            title: "Book".to_string(),
3932            price: 19.99,
3933        };
3934
3935        // Create AnyKeypaths for different root/value type combinations
3936        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
3937        let user_age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
3938        let product_title_kp = KpType::new(
3939            |p: &Product| Some(&p.title),
3940            |p: &mut Product| Some(&mut p.title),
3941        );
3942        let product_price_kp = KpType::new(
3943            |p: &Product| Some(&p.price),
3944            |p: &mut Product| Some(&mut p.price),
3945        );
3946
3947        let all_keypaths: Vec<AKp> = vec![
3948            AKp::new(user_name_kp),
3949            AKp::new(user_age_kp),
3950            AKp::new(product_title_kp),
3951            AKp::new(product_price_kp),
3952        ];
3953
3954        // Filter for User root type
3955        let user_kps: Vec<_> = all_keypaths
3956            .iter()
3957            .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
3958            .collect();
3959
3960        assert_eq!(user_kps.len(), 2);
3961
3962        // Filter for Product root type
3963        let product_kps: Vec<_> = all_keypaths
3964            .iter()
3965            .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
3966            .collect();
3967
3968        assert_eq!(product_kps.len(), 2);
3969
3970        // Filter for String value type
3971        let string_value_kps: Vec<_> = all_keypaths
3972            .iter()
3973            .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
3974            .collect();
3975
3976        assert_eq!(string_value_kps.len(), 2);
3977
3978        // Filter for both User root AND String value
3979        let user_string_kps: Vec<_> = all_keypaths
3980            .iter()
3981            .filter(|akp| {
3982                akp.root_type_id() == TypeId::of::<User>()
3983                    && akp.value_type_id() == TypeId::of::<String>()
3984            })
3985            .collect();
3986
3987        assert_eq!(user_string_kps.len(), 1);
3988        assert_eq!(
3989            user_string_kps[0].get_as::<User, String>(&user),
3990            Some(Some(&"Eve".to_string()))
3991        );
3992
3993        // Filter for Product root AND f64 value
3994        let product_f64_kps: Vec<_> = all_keypaths
3995            .iter()
3996            .filter(|akp| {
3997                akp.root_type_id() == TypeId::of::<Product>()
3998                    && akp.value_type_id() == TypeId::of::<f64>()
3999            })
4000            .collect();
4001
4002        assert_eq!(product_f64_kps.len(), 1);
4003        assert_eq!(
4004            product_f64_kps[0].get_as::<Product, f64>(&product),
4005            Some(Some(&19.99))
4006        );
4007    }
4008
4009    #[test]
4010    fn test_akp_filter_by_arc_root_type() {
4011        use std::any::TypeId;
4012        use std::sync::Arc;
4013
4014        #[derive(Debug)]
4015        struct User {
4016            name: String,
4017        }
4018
4019        #[derive(Debug)]
4020        struct Product {
4021            title: String,
4022        }
4023
4024        let user = User {
4025            name: "Frank".to_string(),
4026        };
4027        let product = Product {
4028            title: "Laptop".to_string(),
4029        };
4030
4031        // Create keypaths
4032        let user_name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4033        let product_title_kp = KpType::new(
4034            |p: &Product| Some(&p.title),
4035            |p: &mut Product| Some(&mut p.title),
4036        );
4037
4038        // Create AKp and adapt for Arc
4039        let user_akp = AKp::new(user_name_kp).for_arc::<User>();
4040        let product_akp = AKp::new(product_title_kp).for_arc::<Product>();
4041
4042        let all_keypaths: Vec<AKp> = vec![user_akp, product_akp];
4043
4044        // Filter for Arc<User> root type
4045        let arc_user_kps: Vec<_> = all_keypaths
4046            .iter()
4047            .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4048            .collect();
4049
4050        assert_eq!(arc_user_kps.len(), 1);
4051
4052        // Verify it works with Arc<User>
4053        let arc_user = Arc::new(user);
4054        assert_eq!(
4055            arc_user_kps[0].get_as::<Arc<User>, String>(&arc_user),
4056            Some(Some(&"Frank".to_string()))
4057        );
4058
4059        // Filter for Arc<Product> root type
4060        let arc_product_kps: Vec<_> = all_keypaths
4061            .iter()
4062            .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<Product>>())
4063            .collect();
4064
4065        assert_eq!(arc_product_kps.len(), 1);
4066
4067        // Verify it works with Arc<Product>
4068        let arc_product = Arc::new(product);
4069        assert_eq!(
4070            arc_product_kps[0].get_as::<Arc<Product>, String>(&arc_product),
4071            Some(Some(&"Laptop".to_string()))
4072        );
4073    }
4074
4075    #[test]
4076    fn test_akp_filter_by_box_root_type() {
4077        use std::any::TypeId;
4078
4079        #[derive(Debug)]
4080        struct Config {
4081            setting: String,
4082        }
4083
4084        let config = Config {
4085            setting: "enabled".to_string(),
4086        };
4087
4088        // Create keypath for regular Config
4089        let config_kp1 = KpType::new(
4090            |c: &Config| Some(&c.setting),
4091            |c: &mut Config| Some(&mut c.setting),
4092        );
4093        let config_kp2 = KpType::new(
4094            |c: &Config| Some(&c.setting),
4095            |c: &mut Config| Some(&mut c.setting),
4096        );
4097
4098        // Create both regular and Box-adapted AKp
4099        let regular_akp = AKp::new(config_kp1);
4100        let box_akp = AKp::new(config_kp2).for_box::<Config>();
4101
4102        let all_keypaths: Vec<AKp> = vec![regular_akp, box_akp];
4103
4104        // Filter for Config root type
4105        let config_kps: Vec<_> = all_keypaths
4106            .iter()
4107            .filter(|akp| akp.root_type_id() == TypeId::of::<Config>())
4108            .collect();
4109
4110        assert_eq!(config_kps.len(), 1);
4111        assert_eq!(
4112            config_kps[0].get_as::<Config, String>(&config),
4113            Some(Some(&"enabled".to_string()))
4114        );
4115
4116        // Filter for Box<Config> root type
4117        let box_config_kps: Vec<_> = all_keypaths
4118            .iter()
4119            .filter(|akp| akp.root_type_id() == TypeId::of::<Box<Config>>())
4120            .collect();
4121
4122        assert_eq!(box_config_kps.len(), 1);
4123
4124        // Verify it works with Box<Config>
4125        let box_config = Box::new(Config {
4126            setting: "enabled".to_string(),
4127        });
4128        assert_eq!(
4129            box_config_kps[0].get_as::<Box<Config>, String>(&box_config),
4130            Some(Some(&"enabled".to_string()))
4131        );
4132    }
4133
4134    #[test]
4135    fn test_mixed_collection_type_filtering() {
4136        use std::any::TypeId;
4137        use std::sync::Arc;
4138
4139        #[derive(Debug)]
4140        struct User {
4141            name: String,
4142            email: String,
4143        }
4144
4145        #[derive(Debug)]
4146        struct Product {
4147            title: String,
4148            sku: String,
4149        }
4150
4151        let user = User {
4152            name: "Grace".to_string(),
4153            email: "grace@example.com".to_string(),
4154        };
4155
4156        let product = Product {
4157            title: "Widget".to_string(),
4158            sku: "WID-001".to_string(),
4159        };
4160
4161        // Create a complex heterogeneous collection
4162        let user_name_kp1 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4163        let user_name_kp2 = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
4164        let user_email_kp1 =
4165            KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4166        let user_email_kp2 =
4167            KpType::new(|u: &User| Some(&u.email), |u: &mut User| Some(&mut u.email));
4168        let product_title_kp = KpType::new(
4169            |p: &Product| Some(&p.title),
4170            |p: &mut Product| Some(&mut p.title),
4171        );
4172        let product_sku_kp = KpType::new(
4173            |p: &Product| Some(&p.sku),
4174            |p: &mut Product| Some(&mut p.sku),
4175        );
4176
4177        let all_keypaths: Vec<AKp> = vec![
4178            AKp::new(user_name_kp1),
4179            AKp::new(user_email_kp1),
4180            AKp::new(product_title_kp),
4181            AKp::new(product_sku_kp),
4182            AKp::new(user_name_kp2).for_arc::<User>(),
4183            AKp::new(user_email_kp2).for_box::<User>(),
4184        ];
4185
4186        // Test 1: Find all keypaths with String values
4187        let string_value_kps: Vec<_> = all_keypaths
4188            .iter()
4189            .filter(|akp| akp.value_type_id() == TypeId::of::<String>())
4190            .collect();
4191
4192        assert_eq!(string_value_kps.len(), 6); // All return String
4193
4194        // Test 2: Find keypaths with User root (excluding Arc<User> and Box<User>)
4195        let user_root_kps: Vec<_> = all_keypaths
4196            .iter()
4197            .filter(|akp| akp.root_type_id() == TypeId::of::<User>())
4198            .collect();
4199
4200        assert_eq!(user_root_kps.len(), 2);
4201
4202        // Test 3: Find keypaths with Arc<User> root
4203        let arc_user_kps: Vec<_> = all_keypaths
4204            .iter()
4205            .filter(|akp| akp.root_type_id() == TypeId::of::<Arc<User>>())
4206            .collect();
4207
4208        assert_eq!(arc_user_kps.len(), 1);
4209
4210        // Test 4: Find keypaths with Box<User> root
4211        let box_user_kps: Vec<_> = all_keypaths
4212            .iter()
4213            .filter(|akp| akp.root_type_id() == TypeId::of::<Box<User>>())
4214            .collect();
4215
4216        assert_eq!(box_user_kps.len(), 1);
4217
4218        // Test 5: Find Product keypaths (non-wrapped)
4219        let product_kps: Vec<_> = all_keypaths
4220            .iter()
4221            .filter(|akp| akp.root_type_id() == TypeId::of::<Product>())
4222            .collect();
4223
4224        assert_eq!(product_kps.len(), 2);
4225
4226        // Test 6: Verify we can use the filtered keypaths
4227        let user_value = user_root_kps[0].get_as::<User, String>(&user);
4228        assert!(user_value.is_some());
4229        assert!(user_value.unwrap().is_some());
4230    }
4231
4232    // ========================================================================
4233    // Advanced Type Examples: Pin, MaybeUninit, Weak
4234    // ========================================================================
4235
4236    #[test]
4237    fn test_kp_with_pin() {
4238        use std::pin::Pin;
4239
4240        // Pin ensures a value won't be moved in memory
4241        // Useful for self-referential structs and async
4242
4243        #[derive(Debug)]
4244        struct SelfReferential {
4245            value: String,
4246            ptr_to_value: *const String, // Points to value field
4247        }
4248
4249        impl SelfReferential {
4250            fn new(s: String) -> Self {
4251                let mut sr = Self {
4252                    value: s,
4253                    ptr_to_value: std::ptr::null(),
4254                };
4255                // Make it self-referential
4256                sr.ptr_to_value = &sr.value as *const String;
4257                sr
4258            }
4259
4260            fn get_value(&self) -> &str {
4261                &self.value
4262            }
4263        }
4264
4265        // Create a pinned value
4266        let boxed = Box::new(SelfReferential::new("pinned_data".to_string()));
4267        let pinned: Pin<Box<SelfReferential>> = Box::into_pin(boxed);
4268
4269        // Keypath to access the value field through Pin
4270        let kp: KpType<Pin<Box<SelfReferential>>, String> = Kp::new(
4271            |p: &Pin<Box<SelfReferential>>| {
4272                // Pin::as_ref() gives us &SelfReferential
4273                Some(&p.as_ref().get_ref().value)
4274            },
4275            |p: &mut Pin<Box<SelfReferential>>| {
4276                // For mutable access, we need to use unsafe get_unchecked_mut
4277                // In practice, you'd use Pin::get_mut if T: Unpin
4278                unsafe {
4279                    let sr = Pin::get_unchecked_mut(p.as_mut());
4280                    Some(&mut sr.value)
4281                }
4282            },
4283        );
4284
4285        // Access through keypath
4286        let result = kp.get(&pinned);
4287        assert_eq!(result, Some(&"pinned_data".to_string()));
4288
4289        // The value is still pinned and hasn't moved
4290        assert_eq!(pinned.get_value(), "pinned_data");
4291    }
4292
4293    #[test]
4294    fn test_kp_with_pin_arc() {
4295        use std::pin::Pin;
4296        use std::sync::Arc;
4297
4298        struct AsyncState {
4299            status: String,
4300            data: Vec<i32>,
4301        }
4302
4303        // Pin<Arc<T>> is common in async Rust
4304        let state = AsyncState {
4305            status: "ready".to_string(),
4306            data: vec![1, 2, 3, 4, 5],
4307        };
4308
4309        let pinned_arc: Pin<Arc<AsyncState>> = Arc::pin(state);
4310
4311        // Keypath to status through Pin<Arc<T>>
4312        let status_kp: KpType<Pin<Arc<AsyncState>>, String> = Kp::new(
4313            |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().status),
4314            |_: &mut Pin<Arc<AsyncState>>| {
4315                // Arc is immutable, so mutable access returns None
4316                None::<&mut String>
4317            },
4318        );
4319
4320        // Keypath to data through Pin<Arc<T>>
4321        let data_kp: KpType<Pin<Arc<AsyncState>>, Vec<i32>> = Kp::new(
4322            |p: &Pin<Arc<AsyncState>>| Some(&p.as_ref().get_ref().data),
4323            |_: &mut Pin<Arc<AsyncState>>| None::<&mut Vec<i32>>,
4324        );
4325
4326        let status = status_kp.get(&pinned_arc);
4327        assert_eq!(status, Some(&"ready".to_string()));
4328
4329        let data = data_kp.get(&pinned_arc);
4330        assert_eq!(data, Some(&vec![1, 2, 3, 4, 5]));
4331    }
4332
4333    #[test]
4334    fn test_kp_with_maybe_uninit() {
4335        use std::mem::MaybeUninit;
4336
4337        // MaybeUninit<T> represents potentially uninitialized memory
4338        // Useful for optimizing initialization or working with FFI
4339
4340        struct Config {
4341            name: MaybeUninit<String>,
4342            value: MaybeUninit<i32>,
4343            initialized: bool,
4344        }
4345
4346        impl Config {
4347            fn new_uninit() -> Self {
4348                Self {
4349                    name: MaybeUninit::uninit(),
4350                    value: MaybeUninit::uninit(),
4351                    initialized: false,
4352                }
4353            }
4354
4355            fn init(&mut self, name: String, value: i32) {
4356                self.name.write(name);
4357                self.value.write(value);
4358                self.initialized = true;
4359            }
4360
4361            fn get_name(&self) -> Option<&String> {
4362                if self.initialized {
4363                    unsafe { Some(self.name.assume_init_ref()) }
4364                } else {
4365                    None
4366                }
4367            }
4368
4369            fn get_value(&self) -> Option<&i32> {
4370                if self.initialized {
4371                    unsafe { Some(self.value.assume_init_ref()) }
4372                } else {
4373                    None
4374                }
4375            }
4376        }
4377
4378        // Create keypath that safely accesses potentially uninitialized data
4379        let name_kp: KpType<Config, String> = Kp::new(
4380            |c: &Config| c.get_name(),
4381            |c: &mut Config| {
4382                if c.initialized {
4383                    unsafe { Some(c.name.assume_init_mut()) }
4384                } else {
4385                    None
4386                }
4387            },
4388        );
4389
4390        let value_kp: KpType<Config, i32> = Kp::new(
4391            |c: &Config| c.get_value(),
4392            |c: &mut Config| {
4393                if c.initialized {
4394                    unsafe { Some(c.value.assume_init_mut()) }
4395                } else {
4396                    None
4397                }
4398            },
4399        );
4400
4401        // Test with uninitialized config
4402        let uninit_config = Config::new_uninit();
4403        assert_eq!(name_kp.get(&uninit_config), None);
4404        assert_eq!(value_kp.get(&uninit_config), None);
4405
4406        // Test with initialized config
4407        let mut init_config = Config::new_uninit();
4408        init_config.init("test_config".to_string(), 42);
4409
4410        assert_eq!(name_kp.get(&init_config), Some(&"test_config".to_string()));
4411        assert_eq!(value_kp.get(&init_config), Some(&42));
4412
4413        // Modify through keypath
4414        if let Some(val) = value_kp.get_mut(&mut init_config) {
4415            *val = 100;
4416        }
4417
4418        assert_eq!(value_kp.get(&init_config), Some(&100));
4419    }
4420
4421    #[test]
4422    fn test_kp_with_weak() {
4423        use std::sync::{Arc, Weak};
4424
4425        // Weak references don't prevent deallocation
4426        // For keypaths with Weak, we need to store the strong reference
4427
4428        #[derive(Debug, Clone)]
4429        struct Node {
4430            value: i32,
4431        }
4432
4433        struct NodeWithParent {
4434            value: i32,
4435            parent: Option<Arc<Node>>, // Strong reference for demonstration
4436        }
4437
4438        let parent = Arc::new(Node { value: 100 });
4439
4440        let child = NodeWithParent {
4441            value: 42,
4442            parent: Some(parent.clone()),
4443        };
4444
4445        // Keypath to access parent value
4446        let parent_value_kp: KpType<NodeWithParent, i32> = Kp::new(
4447            |n: &NodeWithParent| n.parent.as_ref().map(|arc| &arc.value),
4448            |_: &mut NodeWithParent| None::<&mut i32>,
4449        );
4450
4451        // Access parent value
4452        let parent_val = parent_value_kp.get(&child);
4453        assert_eq!(parent_val, Some(&100));
4454    }
4455
4456    #[test]
4457    fn test_kp_with_rc_weak() {
4458        use std::rc::Rc;
4459
4460        // Single-threaded version with Rc
4461
4462        struct TreeNode {
4463            value: String,
4464            parent: Option<Rc<TreeNode>>, // Strong ref for keypath access
4465        }
4466
4467        let root = Rc::new(TreeNode {
4468            value: "root".to_string(),
4469            parent: None,
4470        });
4471
4472        let child1 = TreeNode {
4473            value: "child1".to_string(),
4474            parent: Some(root.clone()),
4475        };
4476
4477        let child2 = TreeNode {
4478            value: "child2".to_string(),
4479            parent: Some(root.clone()),
4480        };
4481
4482        // Keypath to access parent's value
4483        let parent_name_kp: KpType<TreeNode, String> = Kp::new(
4484            |node: &TreeNode| node.parent.as_ref().map(|rc| &rc.value),
4485            |_: &mut TreeNode| None::<&mut String>,
4486        );
4487
4488        // Access parent
4489        assert_eq!(parent_name_kp.get(&child1), Some(&"root".to_string()));
4490        assert_eq!(parent_name_kp.get(&child2), Some(&"root".to_string()));
4491
4492        // Root has no parent
4493        assert_eq!(parent_name_kp.get(&root), None);
4494    }
4495
4496    #[test]
4497    fn test_kp_with_complex_weak_structure() {
4498        use std::sync::Arc;
4499
4500        // Complex structure demonstrating Arc reference patterns
4501
4502        struct Cache {
4503            data: String,
4504            backup: Option<Arc<Cache>>, // Strong reference
4505        }
4506
4507        let primary = Arc::new(Cache {
4508            data: "primary_data".to_string(),
4509            backup: None,
4510        });
4511
4512        let backup = Arc::new(Cache {
4513            data: "backup_data".to_string(),
4514            backup: Some(primary.clone()),
4515        });
4516
4517        // Keypath to access backup's data
4518        let backup_data_kp: KpType<Arc<Cache>, String> = Kp::new(
4519            |cache_arc: &Arc<Cache>| cache_arc.backup.as_ref().map(|arc| &arc.data),
4520            |_: &mut Arc<Cache>| None::<&mut String>,
4521        );
4522
4523        // Access primary data through backup's reference
4524        let data = backup_data_kp.get(&backup);
4525        assert_eq!(data, Some(&"primary_data".to_string()));
4526
4527        // Primary has no backup
4528        let no_backup = backup_data_kp.get(&primary);
4529        assert_eq!(no_backup, None);
4530    }
4531
4532    #[test]
4533    fn test_kp_chain_with_pin_and_arc() {
4534        use std::pin::Pin;
4535        use std::sync::Arc;
4536
4537        // Demonstrate chaining keypaths through Pin and Arc
4538
4539        struct Outer {
4540            inner: Arc<Inner>,
4541        }
4542
4543        struct Inner {
4544            value: String,
4545        }
4546
4547        let outer = Outer {
4548            inner: Arc::new(Inner {
4549                value: "nested_value".to_string(),
4550            }),
4551        };
4552
4553        let pinned_outer = Box::pin(outer);
4554
4555        // First keypath: Pin<Box<Outer>> -> Arc<Inner>
4556        let to_inner: KpType<Pin<Box<Outer>>, Arc<Inner>> = Kp::new(
4557            |p: &Pin<Box<Outer>>| Some(&p.as_ref().get_ref().inner),
4558            |_: &mut Pin<Box<Outer>>| None::<&mut Arc<Inner>>,
4559        );
4560
4561        // Second keypath: Arc<Inner> -> String
4562        let to_value: KpType<Arc<Inner>, String> = Kp::new(
4563            |a: &Arc<Inner>| Some(&a.value),
4564            |_: &mut Arc<Inner>| None::<&mut String>,
4565        );
4566
4567        // Chain them together
4568        let chained = to_inner.then(to_value);
4569
4570        let result = chained.get(&pinned_outer);
4571        assert_eq!(result, Some(&"nested_value".to_string()));
4572    }
4573
4574    #[test]
4575    fn test_kp_with_maybe_uninit_array() {
4576        use std::mem::MaybeUninit;
4577
4578        // Working with arrays of MaybeUninit - common pattern for
4579        // efficient array initialization
4580
4581        struct Buffer {
4582            data: [MaybeUninit<u8>; 10],
4583            len: usize,
4584        }
4585
4586        impl Buffer {
4587            fn new() -> Self {
4588                Self {
4589                    data: unsafe { MaybeUninit::uninit().assume_init() },
4590                    len: 0,
4591                }
4592            }
4593
4594            fn push(&mut self, byte: u8) -> Result<(), &'static str> {
4595                if self.len >= self.data.len() {
4596                    return Err("Buffer full");
4597                }
4598                self.data[self.len].write(byte);
4599                self.len += 1;
4600                Ok(())
4601            }
4602
4603            fn get(&self, idx: usize) -> Option<&u8> {
4604                if idx < self.len {
4605                    unsafe { Some(self.data[idx].assume_init_ref()) }
4606                } else {
4607                    None
4608                }
4609            }
4610
4611            fn get_mut(&mut self, idx: usize) -> Option<&mut u8> {
4612                if idx < self.len {
4613                    unsafe { Some(self.data[idx].assume_init_mut()) }
4614                } else {
4615                    None
4616                }
4617            }
4618        }
4619
4620        // Keypath to access length of initialized data
4621        let len_kp: KpType<Buffer, usize> =
4622            Kp::new(|b: &Buffer| Some(&b.len), |b: &mut Buffer| Some(&mut b.len));
4623
4624        let mut buffer = Buffer::new();
4625
4626        // Empty buffer
4627        assert_eq!(len_kp.get(&buffer), Some(&0));
4628
4629        // Add some data
4630        buffer.push(1).unwrap();
4631        buffer.push(2).unwrap();
4632        buffer.push(3).unwrap();
4633
4634        // Access through keypath
4635        assert_eq!(len_kp.get(&buffer), Some(&3));
4636
4637        // Access elements directly (not through keypath factory due to type complexity)
4638        assert_eq!(buffer.get(0), Some(&1));
4639        assert_eq!(buffer.get(1), Some(&2));
4640        assert_eq!(buffer.get(2), Some(&3));
4641        assert_eq!(buffer.get(10), None); // Out of bounds
4642
4643        // Modify through buffer's API
4644        if let Some(elem) = buffer.get_mut(1) {
4645            *elem = 20;
4646        }
4647        assert_eq!(buffer.get(1), Some(&20));
4648    }
4649
4650    #[test]
4651    fn test_kp_then_lock_deep_structs() {
4652        use std::sync::{Arc, Mutex};
4653
4654        #[derive(Clone)]
4655        struct Root {
4656            guard: Arc<Mutex<Level1>>,
4657        }
4658        #[derive(Clone)]
4659        struct Level1 {
4660            name: String,
4661            nested: Level2,
4662        }
4663        #[derive(Clone)]
4664        struct Level2 {
4665            count: i32,
4666        }
4667
4668        let root = Root {
4669            guard: Arc::new(Mutex::new(Level1 {
4670                name: "deep".to_string(),
4671                nested: Level2 { count: 42 },
4672            })),
4673        };
4674
4675        let kp_to_guard: KpType<Root, Arc<Mutex<Level1>>> =
4676            Kp::new(|r: &Root| Some(&r.guard), |r: &mut Root| Some(&mut r.guard));
4677
4678        let lock_kp = {
4679            let prev: KpType<Arc<Mutex<Level1>>, Arc<Mutex<Level1>>> =
4680                Kp::new(|g: &Arc<Mutex<Level1>>| Some(g), |g: &mut Arc<Mutex<Level1>>| Some(g));
4681            let next: KpType<Level1, Level1> =
4682                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4683            crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4684        };
4685
4686        let chained = kp_to_guard.then_lock(lock_kp);
4687        let level1 = chained.get(&root);
4688        assert!(level1.is_some());
4689        assert_eq!(level1.unwrap().name, "deep");
4690        assert_eq!(level1.unwrap().nested.count, 42);
4691
4692        let mut_root = &mut root.clone();
4693        let mut_level1 = chained.get_mut(mut_root);
4694        assert!(mut_level1.is_some());
4695        mut_level1.unwrap().nested.count = 99;
4696        assert_eq!(chained.get(&root).unwrap().nested.count, 99);
4697    }
4698
4699    #[test]
4700    fn test_kp_then_lock_with_enum() {
4701        use std::sync::{Arc, Mutex};
4702
4703        #[derive(Clone)]
4704        enum Message {
4705            Request(LevelA),
4706            Response(i32),
4707        }
4708        #[derive(Clone)]
4709        struct LevelA {
4710            data: Arc<Mutex<i32>>,
4711        }
4712
4713        struct RootWithEnum {
4714            msg: Arc<Mutex<Message>>,
4715        }
4716
4717        let root = RootWithEnum {
4718            msg: Arc::new(Mutex::new(Message::Request(LevelA {
4719                data: Arc::new(Mutex::new(100)),
4720            }))),
4721        };
4722
4723        let kp_msg: KpType<RootWithEnum, Arc<Mutex<Message>>> =
4724            Kp::new(|r: &RootWithEnum| Some(&r.msg), |r: &mut RootWithEnum| Some(&mut r.msg));
4725
4726        let lock_kp_msg = {
4727            let prev: KpType<Arc<Mutex<Message>>, Arc<Mutex<Message>>> =
4728                Kp::new(|m: &Arc<Mutex<Message>>| Some(m), |m: &mut Arc<Mutex<Message>>| Some(m));
4729            let next: KpType<Message, Message> =
4730                Kp::new(|m: &Message| Some(m), |m: &mut Message| Some(m));
4731            crate::lock::LockKp::new(prev, crate::lock::ArcMutexAccess::new(), next)
4732        };
4733
4734        let chained = kp_msg.then_lock(lock_kp_msg);
4735        let msg = chained.get(&root);
4736        assert!(msg.is_some());
4737        match msg.unwrap() {
4738            Message::Request(a) => assert_eq!(*a.data.lock().unwrap(), 100),
4739            Message::Response(_) => panic!("expected Request"),
4740        }
4741    }
4742
4743    #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4744    #[tokio::test]
4745    async fn test_kp_then_async_deep_chain() {
4746        use std::sync::Arc;
4747        use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4748
4749        #[derive(Clone)]
4750        struct Root {
4751            tokio_guard: Arc<tokio::sync::Mutex<Level1>>,
4752        }
4753        #[derive(Clone)]
4754        struct Level1 {
4755            value: i32,
4756        }
4757
4758        let root = Root {
4759            tokio_guard: Arc::new(tokio::sync::Mutex::new(Level1 { value: 7 })),
4760        };
4761
4762        let kp_to_guard: KpType<Root, Arc<tokio::sync::Mutex<Level1>>> = Kp::new(
4763            |r: &Root| Some(&r.tokio_guard),
4764            |r: &mut Root| Some(&mut r.tokio_guard),
4765        );
4766
4767        let async_kp = {
4768            let prev: KpType<Arc<tokio::sync::Mutex<Level1>>, Arc<tokio::sync::Mutex<Level1>>> =
4769                Kp::new(
4770                    |g: &Arc<tokio::sync::Mutex<Level1>>| Some(g),
4771                    |g: &mut Arc<tokio::sync::Mutex<Level1>>| Some(g),
4772                );
4773            let next: KpType<Level1, Level1> =
4774                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4775            AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4776        };
4777
4778        let chained = kp_to_guard.then_async(async_kp);
4779        let level1 = chained.get(&root).await;
4780        assert!(level1.is_some());
4781        assert_eq!(level1.unwrap().value, 7);
4782    }
4783
4784    /// Deeply nested struct: Root -> sync lock -> L1 -> L2 -> tokio lock -> L3 -> leaf i32.
4785    /// Chain: LockKp(Root->L1) . then(L1->L2) . then(L2->tokio) . then_async(tokio->L3) . then(L3->leaf)
4786    #[cfg(all(feature = "tokio", feature = "parking_lot"))]
4787    #[tokio::test]
4788    async fn test_deep_nested_chain_kp_lock_async_lock_kp() {
4789        use std::sync::{Arc, Mutex};
4790        use crate::async_lock::{AsyncLockKp, TokioMutexAccess};
4791        use crate::lock::{LockKp, ArcMutexAccess};
4792
4793        // Root -> Arc<Mutex<L1>>
4794        #[derive(Clone)]
4795        struct Root {
4796            sync_mutex: Arc<Mutex<Level1>>,
4797        }
4798        // L1 -> Level2 (plain)
4799        #[derive(Clone)]
4800        struct Level1 {
4801            inner: Level2,
4802        }
4803        // L2 -> Arc<TokioMutex<Level3>>
4804        #[derive(Clone)]
4805        struct Level2 {
4806            tokio_mutex: Arc<tokio::sync::Mutex<Level3>>,
4807        }
4808        // L3 -> leaf i32
4809        #[derive(Clone)]
4810        struct Level3 {
4811            leaf: i32,
4812        }
4813
4814        let mut root = Root {
4815            sync_mutex: Arc::new(Mutex::new(Level1 {
4816                inner: Level2 {
4817                    tokio_mutex: Arc::new(tokio::sync::Mutex::new(Level3 { leaf: 42 })),
4818                },
4819            })),
4820        };
4821
4822        // LockKp from Root -> Level1
4823        let identity_l1: KpType<Level1, Level1> =
4824            Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
4825        let kp_sync: KpType<Root, Arc<Mutex<Level1>>> =
4826            Kp::new(|r: &Root| Some(&r.sync_mutex), |r: &mut Root| Some(&mut r.sync_mutex));
4827        let lock_root_to_l1 = LockKp::new(kp_sync, ArcMutexAccess::new(), identity_l1);
4828
4829        // Kp: Level1 -> Level2
4830        let kp_l1_inner: KpType<Level1, Level2> =
4831            Kp::new(|l: &Level1| Some(&l.inner), |l: &mut Level1| Some(&mut l.inner));
4832
4833        // Kp: Level2 -> Arc<TokioMutex<Level3>>
4834        let kp_l2_tokio: KpType<Level2, Arc<tokio::sync::Mutex<Level3>>> = Kp::new(
4835            |l: &Level2| Some(&l.tokio_mutex),
4836            |l: &mut Level2| Some(&mut l.tokio_mutex),
4837        );
4838
4839        // AsyncKp: Arc<TokioMutex<Level3>> -> Level3
4840        let async_l3 = {
4841            let prev: KpType<Arc<tokio::sync::Mutex<Level3>>, Arc<tokio::sync::Mutex<Level3>>> =
4842                Kp::new(|t: &_| Some(t), |t: &mut _| Some(t));
4843            let next: KpType<Level3, Level3> =
4844                Kp::new(|l: &Level3| Some(l), |l: &mut Level3| Some(l));
4845            AsyncLockKp::new(prev, TokioMutexAccess::new(), next)
4846        };
4847
4848        // Kp: Level3 -> i32
4849        let kp_l3_leaf: KpType<Level3, i32> =
4850            Kp::new(|l: &Level3| Some(&l.leaf), |l: &mut Level3| Some(&mut l.leaf));
4851
4852        // Build chain: LockKp(Root->L1) . then(L1->L2) . then(L2->tokio) . then_async(tokio->L3) . then(L3->leaf)
4853        let step1 = lock_root_to_l1.then(kp_l1_inner);
4854        let step2 = step1.then(kp_l2_tokio);
4855        let step3 = step2.then_async(async_l3);
4856        let deep_chain = step3.then(kp_l3_leaf);
4857
4858        // Read leaf through full chain (async)
4859        let leaf = deep_chain.get(&root).await;
4860        deep_chain.get_mut(&mut root).await.map(|l| *l = 100);
4861        assert_eq!(leaf, Some(&100));
4862
4863        // Mutate leaf through full chain
4864        let mut root_mut = root.clone();
4865        let leaf_mut = deep_chain.get_mut(&mut root_mut).await;
4866        assert!(leaf_mut.is_some());
4867        *leaf_mut.unwrap() = 99;
4868
4869        // Read back
4870        let leaf_after = deep_chain.get(&root_mut).await;
4871        assert_eq!(leaf_after, Some(&99));
4872    }
4873}