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