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