Skip to main content

rust_key_paths/
lib.rs

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