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