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