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