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