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