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