Skip to main content

rust_key_paths/
lib.rs

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