Skip to main content

rust_key_paths/
lib.rs

1// pub type KpType<R, V, Root, Value, MutRoot, MutValue, G, S>
2// where
3//     Root: ,
4//     Value:    Borrow<V>,
5//     MutRoot:  BorrowMut<R>,
6//     MutValue: std::borrow::BorrowMut<V>,
7//     G:        Fn(Root) -> Option<Value>,
8//     S:        Fn(MutRoot) -> Option<MutValue> = Kp<R, V, Root, Value, MutRoot, MutValue, G, S>;
9
10// type Getter<R, V, Root, Value> where Root: std::borrow::Borrow<R>, Value: std::borrow::Borrow<V> = fn(Root) -> Option<Value>;
11// type Setter<R, V> = fn(&'r mut R) -> Option<&'r mut V>;
12
13use std::fmt;
14use std::sync::Arc;
15
16// Export the sync_kp module
17pub mod sync_kp;
18pub mod prelude;
19
20pub use sync_kp::{
21    ArcMutexAccess, ArcRwLockAccess, LockAccess, SyncKp, SyncKpType, RcRefCellAccess,
22    StdMutexAccess, StdRwLockAccess,
23};
24
25#[cfg(feature = "parking_lot")]
26pub use sync_kp::{
27    DirectParkingLotMutexAccess, DirectParkingLotRwLockAccess, ParkingLotMutexAccess,
28    ParkingLotRwLockAccess,
29};
30
31#[cfg(feature = "arc-swap")]
32pub use sync_kp::{ArcArcSwapAccess, ArcArcSwapOptionAccess};
33
34// Export the async_lock module
35pub mod async_lock;
36
37pub mod kptrait;
38
39pub use kptrait::{
40    AccessorTrait, ChainExt, CoercionTrait, HofTrait, KeyPathValueTarget, KpReadable, KpTrait,
41    KPWritable,
42};
43
44// pub struct KpStatic<R, V> {
45//     pub get: fn(&R) -> Option<&V>,
46//     pub set: fn(&mut R) -> Option<&mut V>,
47// }
48//
49// // KpStatic holds only fn pointers; it is a functional component with no owned data.
50// unsafe impl<R, V> Send for KpStatic<R, V> {}
51// unsafe impl<R, V> Sync for KpStatic<R, V> {}
52//
53// impl<R, V> KpStatic<R, V> {
54//     pub const fn new(
55//         get: fn(&R) -> Option<&V>,
56//         set: fn(&mut R) -> Option<&mut V>,
57//     ) -> Self {
58//         Self { get, set }
59//     }
60//
61//     #[inline(always)]
62//     pub fn get<'a>(&self, root: &'a R) -> Option<&'a V> {
63//         (self.get)(root)
64//     }
65//
66//     #[inline(always)]
67//     pub fn set<'a>(&self, root: &'a mut R) -> Option<&'a mut V> {
68//         (self.set)(root)
69//     }
70// }
71
72// // Macro generates:
73// #[inline(always)]
74// fn __get_static_str_field(x: &AllContainersTest) -> Option<&'static str> {
75//     Some(&x.static_str_field)
76// }
77//
78// #[inline(always)]
79// fn __set_static_str_field(x: &mut AllContainersTest) -> Option<&mut &'static str> {
80//     Some(&mut x.static_str_field)
81// }
82//
83// pub static STATIC_STR_FIELD_KP: KpStatic<AllContainersTest, &'static str> =
84//     KpStatic::new(__get_static_str_field, __set_static_str_field);
85
86#[cfg(feature = "pin_project")]
87pub mod pin;
88
89/// Build a keypath from `Type.field` segments. Use with types that have keypath accessors (e.g. `#[derive(Kp)]` from key-paths-derive).
90#[macro_export]
91macro_rules! keypath {
92    { $root:ident . $field:ident } => { $root::$field() };
93    { $root:ident . $field:ident . $($ty:ident . $f:ident).+ } => {
94        $root::$field() $(.then($ty::$f()))+
95    };
96    ($root:ident . $field:ident) => { $root::$field() };
97    ($root:ident . $field:ident . $($ty:ident . $f:ident).+) => {
98        $root::$field() $(.then($ty::$f()))+
99    };
100}
101
102/// Get value through a keypath or a default reference when the path returns `None`.
103/// Use with `KpType`: `get_or!(User::name(), &user, &default)` where `default` is `&T` (same type as the path value). Returns `&T`.
104/// Path syntax: `get_or!(&user => User.name, &default)`.
105#[macro_export]
106macro_rules! get_or {
107    ($kp:expr, $root:expr, $default:expr) => {
108        $kp.get($root).unwrap_or($default)
109    };
110    ($root:expr => $($path:tt)*, $default:expr) => {
111        $crate::get_or!($crate::keypath!($($path)*), $root, $default)
112    };
113}
114
115/// Get value through a keypath, or compute an owned fallback when the path returns `None`.
116/// Use with `KpType`: `get_or_else!(User::name(), &user, || "default".to_string())`.
117/// Returns `T` (owned). The keypath's value type must be `Clone`. The closure is only called when the path is `None`.
118/// Path syntax: `get_or_else!(&user => (User.name), || "default".to_string())` — path in parentheses.
119#[macro_export]
120macro_rules! get_or_else {
121    ($kp:expr, $root:expr, $closure:expr) => {
122        $kp.get($root).map(|r| r.clone()).unwrap_or_else($closure)
123    };
124    ($root:expr => ($($path:tt)*), $closure:expr) => {
125        $crate::get_or_else!($crate::keypath!($($path)*), $root, $closure)
126    };
127}
128
129/// Zip multiple keypaths on the same root and apply a closure to the tuple of values.
130/// Returns `Some(closure((v1, v2, ...)))` when all keypaths succeed, else `None`.
131///
132/// # Example
133/// ```
134/// use rust_key_paths::{Kp, KpType, zip_with_kp};
135/// struct User { name: String, age: u32, city: String }
136/// let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
137/// let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
138/// let city_kp = KpType::new(|u: &User| Some(&u.city), |u: &mut User| Some(&mut u.city));
139/// let user = User { name: "Akash".into(), age: 30, city: "NYC".into() };
140/// let summary = zip_with_kp!(
141///     &user,
142///     |(name, age, city)| format!("{}, {} from {}", name, age, city) =>
143///     name_kp,
144///     age_kp,
145///     city_kp
146/// );
147/// assert_eq!(summary, Some("Akash, 30 from NYC".to_string()));
148/// ```
149#[macro_export]
150macro_rules! zip_with_kp {
151    ($root:expr, $closure:expr => $kp1:expr, $kp2:expr) => {
152        match ($kp1.get($root), $kp2.get($root)) {
153            (Some(__a), Some(__b)) => Some($closure((__a, __b))),
154            _ => None,
155        }
156    };
157    ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr) => {
158        match ($kp1.get($root), $kp2.get($root), $kp3.get($root)) {
159            (Some(__a), Some(__b), Some(__c)) => Some($closure((__a, __b, __c))),
160            _ => None,
161        }
162    };
163    ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr) => {
164        match (
165            $kp1.get($root),
166            $kp2.get($root),
167            $kp3.get($root),
168            $kp4.get($root),
169        ) {
170            (Some(__a), Some(__b), Some(__c), Some(__d)) => Some($closure((__a, __b, __c, __d))),
171            _ => None,
172        }
173    };
174    ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr) => {
175        match (
176            $kp1.get($root),
177            $kp2.get($root),
178            $kp3.get($root),
179            $kp4.get($root),
180            $kp5.get($root),
181        ) {
182            (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e)) => {
183                Some($closure((__a, __b, __c, __d, __e)))
184            }
185            _ => None,
186        }
187    };
188    ($root:expr, $closure:expr => $kp1:expr, $kp2:expr, $kp3:expr, $kp4:expr, $kp5:expr, $kp6:expr) => {
189        match (
190            $kp1.get($root),
191            $kp2.get($root),
192            $kp3.get($root),
193            $kp4.get($root),
194            $kp5.get($root),
195            $kp6.get($root),
196        ) {
197            (Some(__a), Some(__b), Some(__c), Some(__d), Some(__e), Some(__f)) => {
198                Some($closure((__a, __b, __c, __d, __e, __f)))
199            }
200            _ => None,
201        }
202    };
203}
204
205/// Kp will force dev to create get and set while value will be owned
206pub type KpValue<'a, R, V> = Kp<
207    R,
208    V,
209    &'a R,
210    V, // Returns owned V, not &V
211    &'a mut R,
212    V, // Returns owned V, not &mut V
213    for<'b> fn(&'b R) -> Option<V>,
214    for<'b> fn(&'b mut R) -> Option<V>,
215>;
216
217/// Kp will force dev to create get and set while root and value both will be owned
218pub type KpOwned<R, V> = Kp<
219    R,
220    V,
221    R,
222    V, // Returns owned V, not &V
223    R,
224    V, // Returns owned V, not &mut V
225    fn(R) -> Option<V>,
226    fn(R) -> Option<V>,
227>;
228
229/// Kp will force dev to create get and set while taking full ownership of the Root while returning Root as value.
230pub type KpRoot<R> = Kp<
231    R,
232    R,
233    R,
234    R, // Returns owned V, not &V
235    R,
236    R, // Returns owned V, not &mut V
237    fn(R) -> Option<R>,
238    fn(R) -> Option<R>,
239>;
240
241/// Kp for void - experimental
242pub type KpVoid = Kp<(), (), (), (), (), (), fn() -> Option<()>, fn() -> Option<()>>;
243
244pub type KpDynamic<R, V> = Kp<
245    R,
246    V,
247    &'static R,
248    &'static V,
249    &'static mut R,
250    &'static mut V,
251    Box<dyn for<'a> Fn(&'a R) -> Option<&'a V> + Send + Sync>,
252    Box<dyn for<'a> Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync>,
253>;
254
255pub type KpBox<'a, R, V> = Kp<
256    R,
257    V,
258    &'a R,
259    &'a V,
260    &'a mut R,
261    &'a mut V,
262    Box<dyn Fn(&'a R) -> Option<&'a V> + 'a>,
263    Box<dyn Fn(&'a mut R) -> Option<&'a mut V> + 'a>,
264>;
265
266pub type KpArc<'a, R, V> = Kp<
267    R,
268    V,
269    &'a R,
270    &'a V,
271    &'a mut R,
272    &'a mut V,
273    Arc<dyn Fn(&'a R) -> Option<&'a V> + Send + Sync + 'a>,
274    Arc<dyn Fn(&'a mut R) -> Option<&'a mut V> + Send + Sync + 'a>,
275>;
276
277pub type KpType<'a, R, V> = Kp<
278    R,
279    V,
280    &'a R,
281    &'a V,
282    &'a mut R,
283    &'a mut V,
284    for<'b> fn(&'b R) -> Option<&'b V>,
285    for<'b> fn(&'b mut R) -> Option<&'b mut V>,
286>;
287
288pub type KpTraitType<'a, R, V> = dyn KpTrait<
289        R,
290        V,
291        &'a R,
292        &'a V,
293        &'a mut R,
294        &'a mut V,
295        for<'b> fn(&'b R) -> Option<&'b V>,
296        for<'b> fn(&'b mut R) -> Option<&'b mut V>,
297    >;
298
299/// Keypath for `Option<RefCell<T>>`: `get` returns `Option<Ref<V>>` so the caller holds the guard.
300/// Use `.get(root).as_ref().map(std::cell::Ref::deref)` to get `Option<&V>` while the `Ref` is in scope.
301pub type KpOptionRefCellType<'a, R, V> = Kp<
302    R,
303    V,
304    &'a R,
305    std::cell::Ref<'a, V>,
306    &'a mut R,
307    std::cell::RefMut<'a, V>,
308    for<'b> fn(&'b R) -> Option<std::cell::Ref<'b, V>>,
309    for<'b> fn(&'b mut R) -> Option<std::cell::RefMut<'b, V>>,
310>;
311
312impl<'a, R, V> KpType<'a, R, V> {
313    /// Converts this keypath to [KpDynamic] for dynamic dispatch and storage (e.g. in a struct field).
314    #[inline]
315    pub fn to_dynamic(self) -> KpDynamic<R, V> {
316        self.into()
317    }
318}
319
320impl<'a, R, V> From<KpType<'a, R, V>> for KpDynamic<R, V> {
321    #[inline]
322    fn from(kp: KpType<'a, R, V>) -> Self {
323        let get_fn = kp.get;
324        let set_fn = kp.set;
325        Kp::new(
326            Box::new(move |t: &R| get_fn(t)),
327            Box::new(move |t: &mut R| set_fn(t)),
328        )
329    }
330}
331
332impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
333where
334    Root: std::borrow::Borrow<R>,
335    Value: std::borrow::Borrow<V>,
336    MutRoot: std::borrow::BorrowMut<R>,
337    MutValue: std::borrow::BorrowMut<V>,
338    G: Fn(Root) -> Option<Value> + Send + Sync + 'static,
339    S: Fn(MutRoot) -> Option<MutValue> + Send + Sync + 'static,
340    R: 'static,
341    V: 'static,
342{
343    /// Erases getter/setter type into [`KpDynamic`] so you can store composed paths (e.g. after [KpTrait::then]).
344    ///
345    /// `#[derive(Kp)]` methods return [`KpType`] (`fn` pointers); chaining with `.then()` produces opaque closures.
346    /// Neither matches a fixed `KpType<…>` field type—use `KpDynamic<R, V>` and `.into_dynamic()` (or
347    /// [KpType::to_dynamic] for a single segment).
348    ///
349    /// # Safety
350    ///
351    /// This uses a small amount of `unsafe` internally: it re-interprets `&R` / `&mut R` as `Root` / `MutRoot`.
352    /// That matches every [`Kp`] built from this crate’s public API ([`Kp::new`] on reference-shaped handles,
353    /// `#[derive(Kp)]`, and [KpTrait::then] / [Kp::then] on those paths). Do not call this on a custom [`Kp`]
354    /// whose `Root` / `MutRoot` are not layout-compatible with `&R` / `&mut R` or whose getters keep borrows
355    /// alive past the call.
356    #[inline]
357    pub fn into_dynamic(self) -> KpDynamic<R, V> {
358        let g = self.get;
359        let s = self.set;
360        Kp::new(
361            Box::new(move |t: &R| unsafe {
362                // SAFETY: See `into_dynamic` rustdoc. `Root` is `&'_ R` for supported keypaths.
363                // debug_assert_eq!(std::mem::size_of::<Root>(), std::mem::size_of::<&R>());
364                let root: Root = std::mem::transmute_copy(&t);
365                match g(root) {
366                    None => None,
367                    Some(v) => {
368                        let r: &V = std::borrow::Borrow::borrow(&v);
369                        // Well-behaved getters return a view into `*t`; re-attach to this call's `&R`.
370                        Some(std::mem::transmute::<&V, &V>(r))
371                    }
372                }
373            }),
374            Box::new(move |t: &mut R| unsafe {
375                // debug_assert_eq!(std::mem::size_of::<MutRoot>(), std::mem::size_of::<&mut R>());
376                let root: MutRoot = std::mem::transmute_copy(&t);
377                match s(root) {
378                    None => None,
379                    Some(mut v) => {
380                        let r: &mut V = std::borrow::BorrowMut::borrow_mut(&mut v);
381                        Some(std::mem::transmute::<&mut V, &mut V>(r))
382                    }
383                }
384            }),
385        )
386    }
387}
388
389// pub type KpType<R, V> = Kp<
390//     R,
391//     V,
392//     &'static R,
393//     &'static V,
394//     &'static mut R,
395//     &'static mut V,
396//     for<'a> fn(&'a R) -> Option<&'a V>,
397//     for<'a> fn(&'a mut R) -> Option<&'a mut V>,
398// >;
399
400// struct A{
401//     b: std::sync::Arc<std::sync::Mutex<B>>,
402// }
403// struct B{
404//     c: C
405// }
406// struct C{
407//     d: String
408// }
409
410// pub struct SyncKp {
411//     first: KpType<'static, A, B>,
412//     mid: KpType<'static, std::sync::Mutex<B>, B>,
413//     second: KpType<'static, B, C>,
414// }
415//
416// impl SyncKp {
417//     fn then(&self, kp: KpType<'static, B, String>) {
418//
419//     }
420//     fn then_sync() {}
421// }
422
423// New type alias for composed/transformed keypaths
424pub type KpComposed<R, V> = Kp<
425    R,
426    V,
427    &'static R,
428    &'static V,
429    &'static mut R,
430    &'static mut V,
431    Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
432    Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
433>;
434
435impl<R, V>
436    Kp<
437        R,
438        V,
439        &'static R,
440        &'static V,
441        &'static mut R,
442        &'static mut V,
443        Box<dyn for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync>,
444        Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync>,
445    >
446{
447    /// Build a keypath from two closures (e.g. when they capture a variable like an index).
448    /// Same pattern as `Kp::new` in lock.rs; use this when the keypath captures variables.
449    pub fn from_closures<G, S>(get: G, set: S) -> Self
450    where
451        G: for<'b> Fn(&'b R) -> Option<&'b V> + Send + Sync + 'static,
452        S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + Send + Sync + 'static,
453    {
454        Self::new(Box::new(get), Box::new(set))
455    }
456}
457
458pub struct AKp {
459    getter: Rc<dyn for<'r> Fn(&'r dyn Any) -> Option<&'r dyn Any>>,
460    root_type_id: TypeId,
461    value_type_id: TypeId,
462}
463
464impl AKp {
465    /// Create a new AKp from a KpType (the common reference-based keypath)
466    pub fn new<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
467    where
468        R: Any + 'static,
469        V: Any + 'static,
470    {
471        let root_type_id = TypeId::of::<R>();
472        let value_type_id = TypeId::of::<V>();
473        let getter_fn = keypath.get;
474
475        Self {
476            getter: Rc::new(move |any: &dyn Any| {
477                if let Some(root) = any.downcast_ref::<R>() {
478                    getter_fn(root).map(|value: &V| value as &dyn Any)
479                } else {
480                    None
481                }
482            }),
483            root_type_id,
484            value_type_id,
485        }
486    }
487
488    /// Create an AKp from a KpType (alias for `new()`)
489    pub fn from<'a, R, V>(keypath: KpType<'a, R, V>) -> Self
490    where
491        R: Any + 'static,
492        V: Any + 'static,
493    {
494        Self::new(keypath)
495    }
496
497    /// Get the value as a trait object (with root type checking)
498    pub fn get<'r>(&self, root: &'r dyn Any) -> Option<&'r dyn Any> {
499        (self.getter)(root)
500    }
501
502    /// Get the TypeId of the Root type
503    pub fn root_type_id(&self) -> TypeId {
504        self.root_type_id
505    }
506
507    /// Get the TypeId of the Value type
508    pub fn value_type_id(&self) -> TypeId {
509        self.value_type_id
510    }
511
512    /// Try to get the value with full type checking
513    pub fn get_as<'a, Root: Any, Value: Any>(&self, root: &'a Root) -> Option<Option<&'a Value>> {
514        if self.root_type_id == TypeId::of::<Root>() && self.value_type_id == TypeId::of::<Value>()
515        {
516            Some(
517                self.get(root as &dyn Any)
518                    .and_then(|any| any.downcast_ref::<Value>()),
519            )
520        } else {
521            None
522        }
523    }
524
525    /// Get a human-readable name for the value type
526    pub fn kind_name(&self) -> String {
527        format!("{:?}", self.value_type_id)
528    }
529
530    /// Get a human-readable name for the root type
531    pub fn root_kind_name(&self) -> String {
532        format!("{:?}", self.root_type_id)
533    }
534
535    /// Adapt this keypath to work with Arc<Root> instead of Root
536    pub fn for_arc<Root>(&self) -> AKp
537    where
538        Root: Any + 'static,
539    {
540        let value_type_id = self.value_type_id;
541        let getter = self.getter.clone();
542
543        AKp {
544            getter: Rc::new(move |any: &dyn Any| {
545                if let Some(arc) = any.downcast_ref::<Arc<Root>>() {
546                    getter(arc.as_ref() as &dyn Any)
547                } else {
548                    None
549                }
550            }),
551            root_type_id: TypeId::of::<Arc<Root>>(),
552            value_type_id,
553        }
554    }
555
556    /// Adapt this keypath to work with Box<Root> instead of Root
557    pub fn for_box<Root>(&self) -> AKp
558    where
559        Root: Any + 'static,
560    {
561        let value_type_id = self.value_type_id;
562        let getter = self.getter.clone();
563
564        AKp {
565            getter: Rc::new(move |any: &dyn Any| {
566                if let Some(boxed) = any.downcast_ref::<Box<Root>>() {
567                    getter(boxed.as_ref() as &dyn Any)
568                } else {
569                    None
570                }
571            }),
572            root_type_id: TypeId::of::<Box<Root>>(),
573            value_type_id,
574        }
575    }
576
577    /// Adapt this keypath to work with Rc<Root> instead of Root
578    pub fn for_rc<Root>(&self) -> AKp
579    where
580        Root: Any + 'static,
581    {
582        let value_type_id = self.value_type_id;
583        let getter = self.getter.clone();
584
585        AKp {
586            getter: Rc::new(move |any: &dyn Any| {
587                if let Some(rc) = any.downcast_ref::<Rc<Root>>() {
588                    getter(rc.as_ref() as &dyn Any)
589                } else {
590                    None
591                }
592            }),
593            root_type_id: TypeId::of::<Rc<Root>>(),
594            value_type_id,
595        }
596    }
597
598    /// Adapt this keypath to work with Option<Root> instead of Root
599    pub fn for_option<Root>(&self) -> AKp
600    where
601        Root: Any + 'static,
602    {
603        let value_type_id = self.value_type_id;
604        let getter = self.getter.clone();
605
606        AKp {
607            getter: Rc::new(move |any: &dyn Any| {
608                if let Some(opt) = any.downcast_ref::<Option<Root>>() {
609                    opt.as_ref().and_then(|root| getter(root as &dyn Any))
610                } else {
611                    None
612                }
613            }),
614            root_type_id: TypeId::of::<Option<Root>>(),
615            value_type_id,
616        }
617    }
618
619    /// Adapt this keypath to work with Result<Root, E> instead of Root
620    pub fn for_result<Root, E>(&self) -> AKp
621    where
622        Root: Any + 'static,
623        E: Any + 'static,
624    {
625        let value_type_id = self.value_type_id;
626        let getter = self.getter.clone();
627
628        AKp {
629            getter: Rc::new(move |any: &dyn Any| {
630                if let Some(result) = any.downcast_ref::<Result<Root, E>>() {
631                    result
632                        .as_ref()
633                        .ok()
634                        .and_then(|root| getter(root as &dyn Any))
635                } else {
636                    None
637                }
638            }),
639            root_type_id: TypeId::of::<Result<Root, E>>(),
640            value_type_id,
641        }
642    }
643
644    /// Map the value through a transformation function with type checking
645    /// Both original and mapped values must implement Any
646    ///
647    /// # Example
648    /// ```
649    /// use rust_key_paths::{AKp, Kp, KpType};
650    /// struct User { name: String }
651    /// let user = User { name: "Akash".to_string() };
652    /// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
653    /// let name_akp = AKp::new(name_kp);
654    /// let len_akp = name_akp.map::<User, String, _, _>(|s| s.len());
655    /// ```
656    pub fn map<Root, OrigValue, MappedValue, F>(&self, mapper: F) -> AKp
657    where
658        Root: Any + 'static,
659        OrigValue: Any + 'static,
660        MappedValue: Any + 'static,
661        F: Fn(&OrigValue) -> MappedValue + 'static,
662    {
663        let orig_root_type_id = self.root_type_id;
664        let orig_value_type_id = self.value_type_id;
665        let getter = self.getter.clone();
666        let mapped_type_id = TypeId::of::<MappedValue>();
667
668        AKp {
669            getter: Rc::new(move |any_root: &dyn Any| {
670                // Check root type matches
671                if any_root.type_id() == orig_root_type_id {
672                    getter(any_root).and_then(|any_value| {
673                        // Verify the original value type matches
674                        if orig_value_type_id == TypeId::of::<OrigValue>() {
675                            any_value.downcast_ref::<OrigValue>().map(|orig_val| {
676                                let mapped = mapper(orig_val);
677                                // Box the mapped value and return as &dyn Any
678                                Box::leak(Box::new(mapped)) as &dyn Any
679                            })
680                        } else {
681                            None
682                        }
683                    })
684                } else {
685                    None
686                }
687            }),
688            root_type_id: orig_root_type_id,
689            value_type_id: mapped_type_id,
690        }
691    }
692
693    /// Filter the value based on a predicate with full type checking
694    /// Returns None if types don't match or predicate fails
695    ///
696    /// # Example
697    /// ```
698    /// use rust_key_paths::{AKp, Kp, KpType};
699    /// struct User { age: i32 }
700    /// let user = User { age: 30 };
701    /// let age_kp = KpType::new(|u: &User| Some(&u.age), |_| None);
702    /// let age_akp = AKp::new(age_kp);
703    /// let adult_akp = age_akp.filter::<User, i32, _>(|age| *age >= 18);
704    /// ```
705    pub fn filter<Root, Value, F>(&self, predicate: F) -> AKp
706    where
707        Root: Any + 'static,
708        Value: Any + 'static,
709        F: Fn(&Value) -> bool + 'static,
710    {
711        let orig_root_type_id = self.root_type_id;
712        let orig_value_type_id = self.value_type_id;
713        let getter = self.getter.clone();
714
715        AKp {
716            getter: Rc::new(move |any_root: &dyn Any| {
717                // Check root type matches
718                if any_root.type_id() == orig_root_type_id {
719                    getter(any_root).filter(|any_value| {
720                        // Type check value and apply predicate
721                        if orig_value_type_id == TypeId::of::<Value>() {
722                            any_value
723                                .downcast_ref::<Value>()
724                                .map(|val| predicate(val))
725                                .unwrap_or(false)
726                        } else {
727                            false
728                        }
729                    })
730                } else {
731                    None
732                }
733            }),
734            root_type_id: orig_root_type_id,
735            value_type_id: orig_value_type_id,
736        }
737    }
738}
739
740impl fmt::Debug for AKp {
741    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
742        f.debug_struct("AKp")
743            .field("root_type_id", &self.root_type_id)
744            .field("value_type_id", &self.value_type_id)
745            .finish_non_exhaustive()
746    }
747}
748
749impl fmt::Display for AKp {
750    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
751        write!(
752            f,
753            "AKp(root_type_id={:?}, value_type_id={:?})",
754            self.root_type_id, self.value_type_id
755        )
756    }
757}
758
759pub struct PKp<Root> {
760    getter: Rc<dyn for<'r> Fn(&'r Root) -> Option<&'r dyn Any>>,
761    value_type_id: TypeId,
762    _phantom: std::marker::PhantomData<Root>,
763}
764
765impl<Root> PKp<Root>
766where
767    Root: 'static,
768{
769    /// Create a new PKp from a KpType (the common reference-based keypath)
770    pub fn new<'a, V>(keypath: KpType<'a, Root, V>) -> Self
771    where
772        V: Any + 'static,
773    {
774        let value_type_id = TypeId::of::<V>();
775        let getter_fn = keypath.get;
776
777        Self {
778            getter: Rc::new(move |root: &Root| getter_fn(root).map(|val: &V| val as &dyn Any)),
779            value_type_id,
780            _phantom: std::marker::PhantomData,
781        }
782    }
783
784    /// Create a PKp from a KpType (alias for `new()`)
785    pub fn from<'a, V>(keypath: KpType<'a, Root, V>) -> Self
786    where
787        V: Any + 'static,
788    {
789        Self::new(keypath)
790    }
791
792    /// Get the value as a trait object
793    pub fn get<'r>(&self, root: &'r Root) -> Option<&'r dyn Any> {
794        (self.getter)(root)
795    }
796
797    /// Get the TypeId of the Value type
798    pub fn value_type_id(&self) -> TypeId {
799        self.value_type_id
800    }
801
802    /// Try to downcast the result to a specific type
803    pub fn get_as<'a, Value: Any>(&self, root: &'a Root) -> Option<&'a Value> {
804        if self.value_type_id == TypeId::of::<Value>() {
805            self.get(root).and_then(|any| any.downcast_ref::<Value>())
806        } else {
807            None
808        }
809    }
810
811    /// Get a human-readable name for the value type
812    pub fn kind_name(&self) -> String {
813        format!("{:?}", self.value_type_id)
814    }
815
816    /// Adapt this keypath to work with Arc<Root> instead of Root
817    pub fn for_arc(&self) -> PKp<Arc<Root>> {
818        let getter = self.getter.clone();
819        let value_type_id = self.value_type_id;
820
821        PKp {
822            getter: Rc::new(move |arc: &Arc<Root>| getter(arc.as_ref())),
823            value_type_id,
824            _phantom: std::marker::PhantomData,
825        }
826    }
827
828    /// Adapt this keypath to work with Box<Root> instead of Root
829    pub fn for_box(&self) -> PKp<Box<Root>> {
830        let getter = self.getter.clone();
831        let value_type_id = self.value_type_id;
832
833        PKp {
834            getter: Rc::new(move |boxed: &Box<Root>| getter(boxed.as_ref())),
835            value_type_id,
836            _phantom: std::marker::PhantomData,
837        }
838    }
839
840    /// Adapt this keypath to work with Rc<Root> instead of Root
841    pub fn for_rc(&self) -> PKp<Rc<Root>> {
842        let getter = self.getter.clone();
843        let value_type_id = self.value_type_id;
844
845        PKp {
846            getter: Rc::new(move |rc: &Rc<Root>| getter(rc.as_ref())),
847            value_type_id,
848            _phantom: std::marker::PhantomData,
849        }
850    }
851
852    /// Adapt this keypath to work with Option<Root> instead of Root
853    pub fn for_option(&self) -> PKp<Option<Root>> {
854        let getter = self.getter.clone();
855        let value_type_id = self.value_type_id;
856
857        PKp {
858            getter: Rc::new(move |opt: &Option<Root>| opt.as_ref().and_then(|root| getter(root))),
859            value_type_id,
860            _phantom: std::marker::PhantomData,
861        }
862    }
863
864    /// Adapt this keypath to work with Result<Root, E> instead of Root
865    pub fn for_result<E>(&self) -> PKp<Result<Root, E>>
866    where
867        E: 'static,
868    {
869        let getter = self.getter.clone();
870        let value_type_id = self.value_type_id;
871
872        PKp {
873            getter: Rc::new(move |result: &Result<Root, E>| {
874                result.as_ref().ok().and_then(|root| getter(root))
875            }),
876            value_type_id,
877            _phantom: std::marker::PhantomData,
878        }
879    }
880
881    /// Map the value through a transformation function
882    /// The mapped value must also implement Any for type erasure
883    ///
884    /// # Example
885    /// ```
886    /// use rust_key_paths::{Kp, KpType, PKp};
887    /// struct User { name: String }
888    /// let user = User { name: "Akash".to_string() };
889    /// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
890    /// let name_pkp = PKp::new(name_kp);
891    /// let len_pkp = name_pkp.map::<String, _, _>(|s| s.len());
892    /// assert_eq!(len_pkp.get_as::<usize>(&user), Some(&5));
893    /// ```
894    pub fn map<OrigValue, MappedValue, F>(&self, mapper: F) -> PKp<Root>
895    where
896        OrigValue: Any + 'static,
897        MappedValue: Any + 'static,
898        F: Fn(&OrigValue) -> MappedValue + 'static,
899    {
900        let orig_type_id = self.value_type_id;
901        let getter = self.getter.clone();
902        let mapped_type_id = TypeId::of::<MappedValue>();
903
904        PKp {
905            getter: Rc::new(move |root: &Root| {
906                getter(root).and_then(|any_value| {
907                    // Verify the original type matches
908                    if orig_type_id == TypeId::of::<OrigValue>() {
909                        any_value.downcast_ref::<OrigValue>().map(|orig_val| {
910                            let mapped = mapper(orig_val);
911                            // Box the mapped value and return as &dyn Any
912                            // Note: This creates a new allocation
913                            Box::leak(Box::new(mapped)) as &dyn Any
914                        })
915                    } else {
916                        None
917                    }
918                })
919            }),
920            value_type_id: mapped_type_id,
921            _phantom: std::marker::PhantomData,
922        }
923    }
924
925    /// Filter the value based on a predicate with type checking
926    /// Returns None if the type doesn't match or predicate fails
927    ///
928    /// # Example
929    /// ```
930    /// use rust_key_paths::{Kp, KpType, PKp};
931    /// struct User { age: i32 }
932    /// let user = User { age: 30 };
933    /// let age_kp = KpType::new(|u: &User| Some(&u.age), |_| None);
934    /// let age_pkp = PKp::new(age_kp);
935    /// let adult_pkp = age_pkp.filter::<i32, _>(|age| *age >= 18);
936    /// assert_eq!(adult_pkp.get_as::<i32>(&user), Some(&30));
937    /// ```
938    pub fn filter<Value, F>(&self, predicate: F) -> PKp<Root>
939    where
940        Value: Any + 'static,
941        F: Fn(&Value) -> bool + 'static,
942    {
943        let orig_type_id = self.value_type_id;
944        let getter = self.getter.clone();
945
946        PKp {
947            getter: Rc::new(move |root: &Root| {
948                getter(root).filter(|any_value| {
949                    // Type check and apply predicate
950                    if orig_type_id == TypeId::of::<Value>() {
951                        any_value
952                            .downcast_ref::<Value>()
953                            .map(|val| predicate(val))
954                            .unwrap_or(false)
955                    } else {
956                        false
957                    }
958                })
959            }),
960            value_type_id: orig_type_id,
961            _phantom: std::marker::PhantomData,
962        }
963    }
964}
965
966impl<Root> fmt::Debug for PKp<Root> {
967    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968        f.debug_struct("PKp")
969            .field("root_ty", &std::any::type_name::<Root>())
970            .field("value_type_id", &self.value_type_id)
971            .finish_non_exhaustive()
972    }
973}
974
975impl<Root> fmt::Display for PKp<Root> {
976    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977        write!(
978            f,
979            "PKp<{}, value_type_id={:?}>",
980            std::any::type_name::<Root>(),
981            self.value_type_id
982        )
983    }
984}
985
986/// `Kp` — typed keypath with getter/setter closures. See also [AKp] for type-erased keypaths.
987///
988/// # Mutation: get vs get_mut (setter path)
989///
990/// - **[get](Kp::get)** uses the `get` closure (getter): `Fn(Root) -> Option<Value>`
991/// - **[get_mut](Kp::get_mut)** uses the `set` closure (setter): `Fn(MutRoot) -> Option<MutValue>`
992///
993/// When mutating through a Kp, the **setter path** is used—`get_mut` invokes the `set` closure,
994/// not the `get` closure. The getter is for read-only access only.
995///
996/// For manual reference-shaped paths, [`constrain_get`] and [`constrain_set`] help closures satisfy
997/// `for<'b> Fn(&'b R) -> Option<&'b V>`; use [`Kp::get_ref`] / [`Kp::get_mut_ref`] to call them explicitly.
998#[derive(Clone)]
999pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1000where
1001    Root: std::borrow::Borrow<R>,
1002    MutRoot: std::borrow::BorrowMut<R>,
1003    MutValue: std::borrow::BorrowMut<V>,
1004    G: Fn(Root) -> Option<Value>,
1005    S: Fn(MutRoot) -> Option<MutValue>,
1006{
1007    /// Getter closure: used by [`Kp::get`] for read-only access when `G` satisfies the HRTB.
1008    get: G,
1009    /// Setter closure: used by [`Kp::get_mut`] for mutation when `S` satisfies the HRTB.
1010    set: S,
1011    _p: std::marker::PhantomData<(R, V, Root, Value, MutRoot, MutValue)>,
1012}
1013
1014/// Forces the compiler to treat a closure as `for<'b> Fn(&'b R) -> Option<&'b V>`.
1015#[inline]
1016pub fn constrain_get<R, V, F>(f: F) -> F
1017where
1018    F: for<'b> Fn(&'b R) -> Option<&'b V>,
1019{
1020    f
1021}
1022
1023/// Forces the compiler to treat a closure as `for<'b> Fn(&'b mut R) -> Option<&'b mut V>`.
1024#[inline]
1025pub fn constrain_set<R, V, F>(f: F) -> F
1026where
1027    F: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1028{
1029    f
1030}
1031
1032impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1033where
1034    Root: std::borrow::Borrow<R>,
1035    Value: std::borrow::Borrow<V>,
1036    MutRoot: std::borrow::BorrowMut<R>,
1037    MutValue: std::borrow::BorrowMut<V>,
1038    G: Fn(Root) -> Option<Value>,
1039    S: Fn(MutRoot) -> Option<MutValue>,
1040{
1041    pub fn new(get: G, set: S) -> Self {
1042        Self {
1043            get,
1044            set,
1045            _p: std::marker::PhantomData,
1046        }
1047    }
1048
1049    /// Read through the getter closure. For reference-shaped keypaths built with [`constrain_get`]
1050    /// / [`constrain_set`], you can also call this as `kp.get(root)` with `root: Root` (often `&R`).
1051    #[inline]
1052    pub fn get(&self, root: Root) -> Option<Value> {
1053        (self.get)(root)
1054    }
1055
1056    /// Mutate through the setter closure.
1057    #[inline]
1058    pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
1059        (self.set)(root)
1060    }
1061
1062    /// Higher-ranked read when `G: for<'b> Fn(&'b R) -> Option<&'b V>` (e.g. manual keypaths using
1063    /// [`constrain_get`]). Prefer [`get`](Kp::get) for generic [`Kp`] including mapped values.
1064    #[inline]
1065    pub fn get_ref<'a>(&self, root: &'a R) -> Option<&'a V>
1066    where
1067        G: for<'b> Fn(&'b R) -> Option<&'b V>,
1068    {
1069        (self.get)(root)
1070    }
1071
1072    /// Higher-ranked write when `S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>`.
1073    #[inline]
1074    pub fn get_mut_ref<'a>(&self, root: &'a mut R) -> Option<&'a mut V>
1075    where
1076        S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1077    {
1078        (self.set)(root)
1079    }
1080
1081    #[inline]
1082    pub fn then<SV, G2, S2>(
1083        self,
1084        next: Kp<
1085            V,
1086            SV,
1087            &'static V, // ← concrete ref types, not free Value/SubValue/MutSubValue
1088            &'static SV,
1089            &'static mut V,
1090            &'static mut SV,
1091            G2,
1092            S2,
1093        >,
1094    ) -> Kp<
1095        R,
1096        SV,
1097        &'static R,
1098        &'static SV,
1099        &'static mut R,
1100        &'static mut SV,
1101        impl for<'b> Fn(&'b R) -> Option<&'b SV>,
1102        impl for<'b> Fn(&'b mut R) -> Option<&'b mut SV>,
1103    >
1104    where
1105        G: for<'b> Fn(&'b R) -> Option<&'b V>,
1106        S: for<'b> Fn(&'b mut R) -> Option<&'b mut V>,
1107        G2: for<'b> Fn(&'b V) -> Option<&'b SV>,
1108        S2: for<'b> Fn(&'b mut V) -> Option<&'b mut SV>,
1109    {
1110        let first_get = self.get;
1111        let first_set = self.set;
1112        let second_get = next.get;
1113        let second_set = next.set;
1114
1115        Kp::new(
1116            constrain_get(move |root: &R| first_get(root).and_then(|value| second_get(value))),
1117            constrain_set(move |root: &mut R| first_set(root).and_then(|value| second_set(value))),
1118        )
1119    }
1120
1121}
1122
1123impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Debug
1124    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1125where
1126    Root: std::borrow::Borrow<R>,
1127    Value: std::borrow::Borrow<V>,
1128    MutRoot: std::borrow::BorrowMut<R>,
1129    MutValue: std::borrow::BorrowMut<V>,
1130    G: Fn(Root) -> Option<Value>,
1131    S: Fn(MutRoot) -> Option<MutValue>,
1132{
1133    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1134        f.debug_struct("Kp")
1135            .field("root_ty", &std::any::type_name::<R>())
1136            .field("value_ty", &std::any::type_name::<V>())
1137            .finish_non_exhaustive()
1138    }
1139}
1140
1141impl<R, V, Root, Value, MutRoot, MutValue, G, S> fmt::Display
1142    for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
1143where
1144    Root: std::borrow::Borrow<R>,
1145    Value: std::borrow::Borrow<V>,
1146    MutRoot: std::borrow::BorrowMut<R>,
1147    MutValue: std::borrow::BorrowMut<V>,
1148    G: Fn(Root) -> Option<Value>,
1149    S: Fn(MutRoot) -> Option<MutValue>,
1150{
1151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1152        write!(
1153            f,
1154            "Kp<{}, {}>",
1155            std::any::type_name::<R>(),
1156            std::any::type_name::<V>()
1157        )
1158    }
1159}
1160
1161/// Zip two keypaths together to create a tuple
1162/// Works only with KpType (reference-based keypaths)
1163///
1164/// # Example
1165/// ```
1166/// use rust_key_paths::{KpType, zip_kps};
1167/// struct User { name: String, age: i32 }
1168/// let user = User { name: "Akash".to_string(), age: 30 };
1169/// let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
1170/// let age_kp = KpType::new(|u: &User| Some(&u.age), |_| None);
1171/// let zipped_fn = zip_kps(&name_kp, &age_kp);
1172/// assert_eq!(zipped_fn(&user), Some((&"Akash".to_string(), &30)));
1173/// ```
1174pub fn zip_kps<'a, RootType, Value1, Value2>(
1175    kp1: &'a KpType<'a, RootType, Value1>,
1176    kp2: &'a KpType<'a, RootType, Value2>,
1177) -> impl Fn(&'a RootType) -> Option<(&'a Value1, &'a Value2)> + 'a
1178where
1179    RootType: 'a,
1180    Value1: 'a,
1181    Value2: 'a,
1182{
1183    move |root: &'a RootType| {
1184        let val1 = (kp1.get)(root)?;
1185        let val2 = (kp2.get)(root)?;
1186        Some((val1, val2))
1187    }
1188}
1189
1190impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
1191where
1192    Root: std::borrow::Borrow<R>,
1193    MutRoot: std::borrow::BorrowMut<R>,
1194    G: Fn(Root) -> Option<Root>,
1195    S: Fn(MutRoot) -> Option<MutRoot>,
1196{
1197    pub fn identity_typed() -> Kp<
1198        R,
1199        R,
1200        Root,
1201        Root,
1202        MutRoot,
1203        MutRoot,
1204        fn(Root) -> Option<Root>,
1205        fn(MutRoot) -> Option<MutRoot>,
1206    > {
1207        Kp::new(|r: Root| Some(r), |r: MutRoot| Some(r))
1208    }
1209
1210    pub fn identity<'a>() -> KpType<'a, R, R> {
1211        KpType::new(|r| Some(r), |r| Some(r))
1212    }
1213}
1214
1215// ========== ENUM KEYPATHS ==========
1216
1217/// EnumKp - A keypath for enum variants that supports both extraction and embedding
1218/// Leverages the existing Kp architecture where optionals are built-in via Option<Value>
1219///
1220/// This struct serves dual purposes:
1221/// 1. As a concrete keypath instance for extracting and embedding enum variants
1222/// 2. As a namespace for static factory methods: `EnumKp::for_ok()`, `EnumKp::for_some()`, etc.
1223pub struct EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1224where
1225    Root: std::borrow::Borrow<Enum>,
1226    Value: std::borrow::Borrow<Variant>,
1227    MutRoot: std::borrow::BorrowMut<Enum>,
1228    MutValue: std::borrow::BorrowMut<Variant>,
1229    G: Fn(Root) -> Option<Value>,
1230    S: Fn(MutRoot) -> Option<MutValue>,
1231    E: Fn(Variant) -> Enum,
1232{
1233    extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1234    embedder: E,
1235}
1236
1237// EnumKp is a functional component; Send/Sync follow from extractor and embedder.
1238unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Send
1239    for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1240where
1241    Root: std::borrow::Borrow<Enum>,
1242    Value: std::borrow::Borrow<Variant>,
1243    MutRoot: std::borrow::BorrowMut<Enum>,
1244    MutValue: std::borrow::BorrowMut<Variant>,
1245    G: Fn(Root) -> Option<Value> + Send,
1246    S: Fn(MutRoot) -> Option<MutValue> + Send,
1247    E: Fn(Variant) -> Enum + Send,
1248{
1249}
1250unsafe impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> Sync
1251    for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1252where
1253    Root: std::borrow::Borrow<Enum>,
1254    Value: std::borrow::Borrow<Variant>,
1255    MutRoot: std::borrow::BorrowMut<Enum>,
1256    MutValue: std::borrow::BorrowMut<Variant>,
1257    G: Fn(Root) -> Option<Value> + Sync,
1258    S: Fn(MutRoot) -> Option<MutValue> + Sync,
1259    E: Fn(Variant) -> Enum + Sync,
1260{
1261}
1262
1263impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1264    EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1265where
1266    Root: std::borrow::Borrow<Enum>,
1267    Value: std::borrow::Borrow<Variant>,
1268    MutRoot: std::borrow::BorrowMut<Enum>,
1269    MutValue: std::borrow::BorrowMut<Variant>,
1270    G: Fn(Root) -> Option<Value>,
1271    S: Fn(MutRoot) -> Option<MutValue>,
1272    E: Fn(Variant) -> Enum,
1273{
1274    /// Create a new EnumKp with extractor and embedder functions
1275    pub fn new(
1276        extractor: Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S>,
1277        embedder: E,
1278    ) -> Self {
1279        Self {
1280            extractor,
1281            embedder,
1282        }
1283    }
1284
1285    /// Extract the variant from an enum (returns None if wrong variant)
1286    pub fn get(&self, enum_value: Root) -> Option<Value> {
1287        (self.extractor.get)(enum_value)
1288    }
1289
1290    /// Extract the variant mutably from an enum (returns None if wrong variant)
1291    pub fn get_mut(&self, enum_value: MutRoot) -> Option<MutValue> {
1292        (self.extractor.set)(enum_value)
1293    }
1294
1295    /// Embed a value into the enum variant
1296    pub fn embed(&self, value: Variant) -> Enum {
1297        (self.embedder)(value)
1298    }
1299
1300    /// Get the underlying Kp for composition with other keypaths
1301    pub fn as_kp(&self) -> &Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1302        &self.extractor
1303    }
1304
1305    /// Convert to Kp (loses embedding capability but gains composition)
1306    pub fn into_kp(self) -> Kp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S> {
1307        self.extractor
1308    }
1309
1310    /// Map the variant value through a transformation function
1311    ///
1312    /// # Example
1313    /// ```
1314    /// use rust_key_paths::enum_ok;
1315    /// let result: Result<String, i32> = Ok("hello".to_string());
1316    /// let ok_kp = enum_ok();
1317    /// let len_kp = ok_kp.map(|s: &String| s.len());
1318    /// assert_eq!(len_kp.get(&result), Some(5));
1319    /// ```
1320    pub fn map<MappedValue, F>(
1321        &self,
1322        mapper: F,
1323    ) -> EnumKp<
1324        Enum,
1325        MappedValue,
1326        Root,
1327        MappedValue,
1328        MutRoot,
1329        MappedValue,
1330        impl Fn(Root) -> Option<MappedValue>,
1331        impl Fn(MutRoot) -> Option<MappedValue>,
1332        impl Fn(MappedValue) -> Enum,
1333    >
1334    where
1335        // Copy: Required because mapper is used via extractor.map() which needs it
1336        // 'static: Required because the returned EnumKp must own its closures
1337        F: Fn(&Variant) -> MappedValue + Copy + 'static,
1338        Variant: 'static,
1339        MappedValue: 'static,
1340        // Copy: Required for embedder to be captured in the panic closure
1341        E: Fn(Variant) -> Enum + Copy + 'static,
1342    {
1343        let mapped_extractor = self.extractor.map(mapper);
1344
1345        // Create a new embedder that maps back
1346        // Note: This is a limitation - we can't reverse the map for embedding
1347        // So we create a placeholder that panics
1348        let new_embedder = move |_value: MappedValue| -> Enum {
1349            panic!(
1350                "Cannot embed mapped values back into enum. Use the original EnumKp for embedding."
1351            )
1352        };
1353
1354        EnumKp::new(mapped_extractor, new_embedder)
1355    }
1356
1357    /// Filter the variant value based on a predicate
1358    /// Returns None if the predicate fails or if wrong variant
1359    ///
1360    /// # Example
1361    /// ```
1362    /// use rust_key_paths::enum_ok;
1363    /// let result: Result<i32, String> = Ok(42);
1364    /// let ok_kp = enum_ok();
1365    /// let positive_kp = ok_kp.filter(|x: &i32| *x > 0);
1366    /// assert_eq!(positive_kp.get(&result), Some(&42));
1367    /// ```
1368    pub fn filter<F>(
1369        &self,
1370        predicate: F,
1371    ) -> EnumKp<
1372        Enum,
1373        Variant,
1374        Root,
1375        Value,
1376        MutRoot,
1377        MutValue,
1378        impl Fn(Root) -> Option<Value>,
1379        impl Fn(MutRoot) -> Option<MutValue>,
1380        E,
1381    >
1382    where
1383        // Copy: Required because predicate is used via extractor.filter() which needs it
1384        // 'static: Required because the returned EnumKp must own its closures
1385        F: Fn(&Variant) -> bool + Copy + 'static,
1386        Variant: 'static,
1387        // Copy: Required to clone embedder into the new EnumKp
1388        E: Copy,
1389    {
1390        let filtered_extractor = self.extractor.filter(predicate);
1391        EnumKp::new(filtered_extractor, self.embedder)
1392    }
1393}
1394
1395impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Debug
1396    for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1397where
1398    Root: std::borrow::Borrow<Enum>,
1399    Value: std::borrow::Borrow<Variant>,
1400    MutRoot: std::borrow::BorrowMut<Enum>,
1401    MutValue: std::borrow::BorrowMut<Variant>,
1402    G: Fn(Root) -> Option<Value>,
1403    S: Fn(MutRoot) -> Option<MutValue>,
1404    E: Fn(Variant) -> Enum,
1405{
1406    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1407        f.debug_struct("EnumKp")
1408            .field("enum_ty", &std::any::type_name::<Enum>())
1409            .field("variant_ty", &std::any::type_name::<Variant>())
1410            .finish_non_exhaustive()
1411    }
1412}
1413
1414impl<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E> fmt::Display
1415    for EnumKp<Enum, Variant, Root, Value, MutRoot, MutValue, G, S, E>
1416where
1417    Root: std::borrow::Borrow<Enum>,
1418    Value: std::borrow::Borrow<Variant>,
1419    MutRoot: std::borrow::BorrowMut<Enum>,
1420    MutValue: std::borrow::BorrowMut<Variant>,
1421    G: Fn(Root) -> Option<Value>,
1422    S: Fn(MutRoot) -> Option<MutValue>,
1423    E: Fn(Variant) -> Enum,
1424{
1425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1426        write!(
1427            f,
1428            "EnumKp<{}, {}>",
1429            std::any::type_name::<Enum>(),
1430            std::any::type_name::<Variant>()
1431        )
1432    }
1433}
1434
1435// Type alias for the common case with references
1436pub type EnumKpType<'a, Enum, Variant> = EnumKp<
1437    Enum,
1438    Variant,
1439    &'a Enum,
1440    &'a Variant,
1441    &'a mut Enum,
1442    &'a mut Variant,
1443    for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1444    for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1445    fn(Variant) -> Enum,
1446>;
1447
1448// Static factory functions for creating EnumKp instances
1449/// Create an enum keypath with both extraction and embedding for a specific variant
1450///
1451/// # Example
1452/// ```
1453/// use rust_key_paths::enum_variant;
1454/// enum MyEnum {
1455///     A(String),
1456///     B(i32),
1457/// }
1458///
1459/// let kp = enum_variant(
1460///     |e: &MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1461///     |e: &mut MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1462///     |s: String| MyEnum::A(s)
1463/// );
1464/// ```
1465pub fn enum_variant<'a, Enum, Variant>(
1466    getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1467    setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1468    embedder: fn(Variant) -> Enum,
1469) -> EnumKpType<'a, Enum, Variant> {
1470    EnumKp::new(Kp::new(getter, setter), embedder)
1471}
1472
1473/// Extract from Result<T, E> - Ok variant
1474///
1475/// # Example
1476/// ```
1477/// use rust_key_paths::enum_ok;
1478/// let result: Result<String, i32> = Ok("success".to_string());
1479/// let ok_kp = enum_ok();
1480/// assert_eq!(ok_kp.get(&result), Some(&"success".to_string()));
1481/// ```
1482pub fn enum_ok<'a, T, E>() -> EnumKpType<'a, Result<T, E>, T> {
1483    EnumKp::new(
1484        Kp::new(
1485            |r: &Result<T, E>| r.as_ref().ok(),
1486            |r: &mut Result<T, E>| r.as_mut().ok(),
1487        ),
1488        |t: T| Ok(t),
1489    )
1490}
1491
1492/// Extract from Result<T, E> - Err variant
1493///
1494/// # Example
1495/// ```
1496/// use rust_key_paths::enum_err;
1497/// let result: Result<String, i32> = Err(42);
1498/// let err_kp = enum_err();
1499/// assert_eq!(err_kp.get(&result), Some(&42));
1500/// ```
1501pub fn enum_err<'a, T, E>() -> EnumKpType<'a, Result<T, E>, E> {
1502    EnumKp::new(
1503        Kp::new(
1504            |r: &Result<T, E>| r.as_ref().err(),
1505            |r: &mut Result<T, E>| r.as_mut().err(),
1506        ),
1507        |e: E| Err(e),
1508    )
1509}
1510
1511/// Extract from Option<T> - Some variant
1512///
1513/// # Example
1514/// ```
1515/// use rust_key_paths::enum_some;
1516/// let opt = Some("value".to_string());
1517/// let some_kp = enum_some();
1518/// assert_eq!(some_kp.get(&opt), Some(&"value".to_string()));
1519/// ```
1520pub fn enum_some<'a, T>() -> EnumKpType<'a, Option<T>, T> {
1521    EnumKp::new(
1522        Kp::new(|o: &Option<T>| o.as_ref(), |o: &mut Option<T>| o.as_mut()),
1523        |t: T| Some(t),
1524    )
1525}
1526
1527// Helper functions for creating enum keypaths with type inference
1528/// Create an enum keypath for a specific variant with type inference
1529///
1530/// # Example
1531/// ```
1532/// use rust_key_paths::variant_of;
1533/// enum MyEnum {
1534///     A(String),
1535///     B(i32),
1536/// }
1537///
1538/// let kp_a = variant_of(
1539///     |e: &MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1540///     |e: &mut MyEnum| match e { MyEnum::A(s) => Some(s), _ => None },
1541///     |s: String| MyEnum::A(s)
1542/// );
1543/// ```
1544pub fn variant_of<'a, Enum, Variant>(
1545    getter: for<'b> fn(&'b Enum) -> Option<&'b Variant>,
1546    setter: for<'b> fn(&'b mut Enum) -> Option<&'b mut Variant>,
1547    embedder: fn(Variant) -> Enum,
1548) -> EnumKpType<'a, Enum, Variant> {
1549    enum_variant(getter, setter, embedder)
1550}
1551
1552// ========== CONTAINER KEYPATHS ==========
1553
1554// Helper functions for working with standard containers (Box, Arc, Rc)
1555/// Create a keypath for unwrapping Box<T> -> T
1556///
1557/// # Example
1558/// ```
1559/// use rust_key_paths::kp_box;
1560/// let boxed = Box::new("value".to_string());
1561/// let kp = kp_box();
1562/// assert_eq!(kp.get(&boxed), Some(&"value".to_string()));
1563/// ```
1564pub fn kp_box<'a, T>() -> KpType<'a, Box<T>, T> {
1565    Kp::new(
1566        |b: &Box<T>| Some(b.as_ref()),
1567        |b: &mut Box<T>| Some(b.as_mut()),
1568    )
1569}
1570
1571/// Create a keypath for unwrapping Arc<T> -> T (read-only)
1572///
1573/// # Example
1574/// ```
1575/// use std::sync::Arc;
1576/// use rust_key_paths::kp_arc;
1577/// let arc = Arc::new("value".to_string());
1578/// let kp = kp_arc();
1579/// assert_eq!(kp.get(&arc), Some(&"value".to_string()));
1580/// ```
1581pub fn kp_arc<'a, T>() -> Kp<
1582    Arc<T>,
1583    T,
1584    &'a Arc<T>,
1585    &'a T,
1586    &'a mut Arc<T>,
1587    &'a mut T,
1588    for<'b> fn(&'b Arc<T>) -> Option<&'b T>,
1589    for<'b> fn(&'b mut Arc<T>) -> Option<&'b mut T>,
1590> {
1591    Kp::new(
1592        |arc: &Arc<T>| Some(arc.as_ref()),
1593        |arc: &mut Arc<T>| Arc::get_mut(arc),
1594    )
1595}
1596
1597/// Create a keypath for unwrapping Rc<T> -> T (read-only)
1598///
1599/// # Example
1600/// ```
1601/// use std::rc::Rc;
1602/// use rust_key_paths::kp_rc;
1603/// let rc = Rc::new("value".to_string());
1604/// let kp = kp_rc();
1605/// assert_eq!(kp.get(&rc), Some(&"value".to_string()));
1606/// ```
1607pub fn kp_rc<'a, T>() -> Kp<
1608    std::rc::Rc<T>,
1609    T,
1610    &'a std::rc::Rc<T>,
1611    &'a T,
1612    &'a mut std::rc::Rc<T>,
1613    &'a mut T,
1614    for<'b> fn(&'b std::rc::Rc<T>) -> Option<&'b T>,
1615    for<'b> fn(&'b mut std::rc::Rc<T>) -> Option<&'b mut T>,
1616> {
1617    Kp::new(
1618        |rc: &std::rc::Rc<T>| Some(rc.as_ref()),
1619        |rc: &mut std::rc::Rc<T>| std::rc::Rc::get_mut(rc),
1620    )
1621}
1622
1623// ========== PARTIAL KEYPATHS (Hide Value Type) ==========
1624
1625use std::any::{Any, TypeId};
1626use std::rc::Rc;