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