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