Skip to main content

rust_key_paths/
lib.rs

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