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