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