Skip to main content

rust_key_paths/
lib.rs

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