Skip to main content

key_paths_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::{format_ident, quote};
3use syn::{Data, DeriveInput, Fields, Type, parse_macro_input, spanned::Spanned};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6enum WrapperKind {
7    None,
8    Option,
9    Box,
10    Rc,
11    Arc,
12    Vec,
13    HashMap,
14    BTreeMap,
15    HashSet,
16    BTreeSet,
17    VecDeque,
18    LinkedList,
19    BinaryHeap,
20    // Error handling containers
21    Result,
22    // Reference counting with weak references
23    Weak,
24    // String and owned text
25    String,
26    OptionString,
27    // Interior mutability (std::cell)
28    Cell,
29    RefCell,
30    OptionCell,
31    OptionRefCell,
32    // Lazy init (once_cell, std::sync::OnceLock, std::sync::LazyLock)
33    OnceCell,
34    Lazy,
35    OptionOnceCell,
36    OptionLazy,
37    // Marker / zero-size
38    PhantomData,
39    OptionPhantomData,
40    // Range iterators (std::ops::Range, RangeInclusive)
41    Range,
42    OptionRange,
43    // Nested container support
44    OptionBox,
45    OptionRc,
46    OptionArc,
47    BoxOption,
48    RcOption,
49    ArcOption,
50    VecOption,
51    OptionVec,
52    VecDequeOption,
53    OptionVecDeque,
54    LinkedListOption,
55    OptionLinkedList,
56    BinaryHeapOption,
57    OptionBinaryHeap,
58    HashSetOption,
59    OptionHashSet,
60    BTreeSetOption,
61    OptionBTreeSet,
62    ResultOption,
63    OptionResult,
64    HashMapOption,
65    OptionHashMap,
66    BTreeMapOption,
67    OptionBTreeMap,
68    // Arc with synchronization primitives (default)
69    StdArcMutex,
70    StdArcRwLock,
71    OptionStdArcMutex,
72    OptionStdArcRwLock,
73    // Synchronization primitives default
74    StdMutex,
75    StdRwLock,
76    OptionStdMutex,
77    OptionStdRwLock,
78    // Synchronization primitives (parking_lot)
79    Mutex,
80    RwLock,
81    OptionMutex,
82    OptionRwLock,
83    // Synchronization primitives (tokio::sync - requires tokio feature)
84    TokioMutex,
85    TokioRwLock,
86    // parking_lot
87    ArcMutex,
88    ArcRwLock,
89    OptionArcMutex,
90    OptionArcRwLock,
91    // Arc with synchronization primitives (tokio::sync - requires tokio feature)
92    TokioArcMutex,
93    TokioArcRwLock,
94    OptionTokioArcMutex,
95    OptionTokioArcRwLock,
96    // Tagged types
97    Tagged,
98    OptionTagged,
99    // Clone-on-write (std::borrow::Cow)
100    Cow,
101    OptionCow,
102    // Reference types (&T, &str, &[T], etc.)
103    Reference,
104    OptionReference,
105    // Atomic types (std::sync::atomic::*)
106    Atomic,
107    OptionAtomic,
108    // Pin types
109    Pin,
110    PinBox,
111    /// Field marked with #[pin] - plain type (pin_project pattern)
112    PinnedField,
113    /// Field marked with #[pin] - Future type (pin_project pattern)
114    PinnedFuture,
115    /// Field marked with #[pin] - Box<dyn Future> (pin_project pattern)
116    PinnedBoxFuture,
117}
118
119/// Helper function to check if a type path includes std::sync module
120fn is_std_sync_type(path: &syn::Path) -> bool {
121    // Check for paths like std::sync::Mutex, std::sync::RwLock
122    let segments: Vec<_> = path.segments.iter().map(|s| s.ident.to_string()).collect();
123    segments.len() >= 2
124        && segments.contains(&"std".to_string())
125        && segments.contains(&"sync".to_string())
126}
127
128/// Helper function to check if a type path includes tokio::sync module
129fn is_tokio_sync_type(path: &syn::Path) -> bool {
130    // Check for paths like tokio::sync::Mutex, tokio::sync::RwLock
131    let segments: Vec<_> = path.segments.iter().map(|s| s.ident.to_string()).collect();
132    segments.len() >= 2
133        && segments.contains(&"tokio".to_string())
134        && segments.contains(&"sync".to_string())
135}
136
137/// Helper function to check if a type path includes std::sync::atomic module
138fn is_std_sync_atomic_type(path: &syn::Path) -> bool {
139    let segments: Vec<_> = path.segments.iter().map(|s| s.ident.to_string()).collect();
140    segments.contains(&"std".to_string())
141        && segments.contains(&"sync".to_string())
142        && segments.contains(&"atomic".to_string())
143}
144
145/// Atomic type idents (no type params): AtomicBool, AtomicI8, etc.
146const ATOMIC_TYPE_IDENTS: &[&str] = &[
147    "AtomicBool", "AtomicI8", "AtomicI16", "AtomicI32", "AtomicI64", "AtomicI128", "AtomicIsize",
148    "AtomicU8", "AtomicU16", "AtomicU32", "AtomicU64", "AtomicU128", "AtomicUsize",
149];
150
151fn extract_wrapper_inner_type(ty: &Type) -> (WrapperKind, Option<Type>) {
152    use syn::{GenericArgument, PathArguments};
153
154    // Handle reference types: &T, &'a str, &[T], etc.
155    if let Type::Reference(tr) = ty {
156        return (WrapperKind::Reference, Some((*tr.elem).clone()));
157    }
158
159    if let Type::Path(tp) = ty {
160        // Check if this is explicitly a std::sync type
161        let is_std_sync = is_std_sync_type(&tp.path);
162        // Check if this is explicitly a tokio::sync type
163        let is_tokio_sync = is_tokio_sync_type(&tp.path);
164
165        if let Some(seg) = tp.path.segments.last() {
166            let ident_str = seg.ident.to_string();
167
168            if let PathArguments::AngleBracketed(ab) = &seg.arguments {
169                let args: Vec<_> = ab.args.iter().collect();
170
171                // Handle map types (HashMap, BTreeMap) - they have K, V parameters
172                if ident_str == "HashMap" || ident_str == "BTreeMap" {
173                    if let (Some(_key_arg), Some(value_arg)) = (args.get(0), args.get(1)) {
174                        if let GenericArgument::Type(inner) = value_arg {
175                            // Check for nested Option in map values
176                            let (inner_kind, inner_inner) = extract_wrapper_inner_type(inner);
177                            match (ident_str.as_str(), inner_kind) {
178                                ("HashMap", WrapperKind::Option) => {
179                                    return (WrapperKind::HashMapOption, inner_inner);
180                                }
181                                ("BTreeMap", WrapperKind::Option) => {
182                                    return (WrapperKind::BTreeMapOption, inner_inner);
183                                }
184                                _ => {
185                                    return match ident_str.as_str() {
186                                        "HashMap" => (WrapperKind::HashMap, Some(inner.clone())),
187                                        "BTreeMap" => (WrapperKind::BTreeMap, Some(inner.clone())),
188                                        _ => (WrapperKind::None, None),
189                                    };
190                                }
191                            }
192                        }
193                    }
194                }
195                // Handle Cow<'a, B> - has lifetime then type parameter
196                else if ident_str == "Cow" {
197                    if let Some(inner) = args.iter().find_map(|arg| {
198                        if let GenericArgument::Type(t) = arg {
199                            Some(t.clone())
200                        } else {
201                            None
202                        }
203                    }) {
204                        return (WrapperKind::Cow, Some(inner));
205                    }
206                }
207                // Handle single-parameter container types
208                else if let Some(arg) = args.get(0) {
209                    if let GenericArgument::Type(inner) = arg {
210                        // Check for nested containers first
211                        let (inner_kind, inner_inner) = extract_wrapper_inner_type(inner);
212
213                        // Handle nested combinations
214                        match (ident_str.as_str(), inner_kind) {
215                            ("Option", WrapperKind::Box) => {
216                                return (WrapperKind::OptionBox, inner_inner);
217                            }
218                            ("Option", WrapperKind::Rc) => {
219                                return (WrapperKind::OptionRc, inner_inner);
220                            }
221                            ("Option", WrapperKind::Arc) => {
222                                return (WrapperKind::OptionArc, inner_inner);
223                            }
224                            ("Option", WrapperKind::Vec) => {
225                                return (WrapperKind::OptionVec, inner_inner);
226                            }
227                            ("Option", WrapperKind::HashMap) => {
228                                return (WrapperKind::OptionHashMap, inner_inner);
229                            }
230                            ("Option", WrapperKind::BTreeMap) => {
231                                return (WrapperKind::OptionBTreeMap, inner_inner);
232                            }
233                            ("Option", WrapperKind::VecDeque) => {
234                                return (WrapperKind::OptionVecDeque, inner_inner);
235                            }
236                            ("Option", WrapperKind::LinkedList) => {
237                                return (WrapperKind::OptionLinkedList, inner_inner);
238                            }
239                            ("Option", WrapperKind::BinaryHeap) => {
240                                return (WrapperKind::OptionBinaryHeap, inner_inner);
241                            }
242                            ("Option", WrapperKind::HashSet) => {
243                                return (WrapperKind::OptionHashSet, inner_inner);
244                            }
245                            ("Option", WrapperKind::BTreeSet) => {
246                                return (WrapperKind::OptionBTreeSet, inner_inner);
247                            }
248                            ("Option", WrapperKind::Result) => {
249                                return (WrapperKind::OptionResult, inner_inner);
250                            }
251                            ("Option", WrapperKind::StdArcMutex) => {
252                                return (WrapperKind::OptionStdArcMutex, inner_inner);
253                            }
254                            ("Option", WrapperKind::StdArcRwLock) => {
255                                return (WrapperKind::OptionStdArcRwLock, inner_inner);
256                            }
257                            ("Option", WrapperKind::ArcMutex) => {
258                                return (WrapperKind::OptionArcMutex, inner_inner);
259                            }
260                            ("Option", WrapperKind::ArcRwLock) => {
261                                return (WrapperKind::OptionArcRwLock, inner_inner);
262                            }
263                            ("Option", WrapperKind::StdMutex) => {
264                                return (WrapperKind::OptionStdMutex, inner_inner);
265                            }
266                            ("Option", WrapperKind::StdRwLock) => {
267                                return (WrapperKind::OptionStdRwLock, inner_inner);
268                            }
269                            ("Option", WrapperKind::Mutex) => {
270                                return (WrapperKind::OptionMutex, inner_inner);
271                            }
272                            ("Option", WrapperKind::RwLock) => {
273                                return (WrapperKind::OptionRwLock, inner_inner);
274                            }
275                            ("Option", WrapperKind::TokioArcMutex) => {
276                                return (WrapperKind::OptionTokioArcMutex, inner_inner);
277                            }
278                            ("Option", WrapperKind::TokioArcRwLock) => {
279                                return (WrapperKind::OptionTokioArcRwLock, inner_inner);
280                            }
281                            ("Option", WrapperKind::Cow) => {
282                                return (WrapperKind::OptionCow, inner_inner);
283                            }
284                            ("Option", WrapperKind::Tagged) => {
285                                return (WrapperKind::OptionTagged, inner_inner);
286                            }
287                            ("Option", WrapperKind::Reference) => {
288                                return (WrapperKind::OptionReference, Some(inner.clone()));
289                            }
290                            ("Option", WrapperKind::Atomic) => {
291                                return (WrapperKind::OptionAtomic, Some(inner.clone()));
292                            }
293                            ("Option", WrapperKind::String) => {
294                                return (WrapperKind::OptionString, None);
295                            }
296                            ("Option", WrapperKind::Cell) => {
297                                return (WrapperKind::OptionCell, inner_inner);
298                            }
299                            ("Option", WrapperKind::RefCell) => {
300                                return (WrapperKind::OptionRefCell, inner_inner);
301                            }
302                            ("Option", WrapperKind::OnceCell) => {
303                                return (WrapperKind::OptionOnceCell, inner_inner);
304                            }
305                            ("Option", WrapperKind::Lazy) => {
306                                return (WrapperKind::OptionLazy, inner_inner);
307                            }
308                            ("Option", WrapperKind::PhantomData) => {
309                                return (WrapperKind::OptionPhantomData, inner_inner);
310                            }
311                            ("Option", WrapperKind::Range) => {
312                                return (WrapperKind::OptionRange, inner_inner);
313                            }
314                            ("Pin", WrapperKind::Box) => {
315                                return (WrapperKind::PinBox, inner_inner);
316                            }
317                            ("Box", WrapperKind::Option) => {
318                                return (WrapperKind::BoxOption, inner_inner);
319                            }
320                            ("Rc", WrapperKind::Option) => {
321                                return (WrapperKind::RcOption, inner_inner);
322                            }
323                            ("Arc", WrapperKind::Option) => {
324                                return (WrapperKind::ArcOption, inner_inner);
325                            }
326                            ("Vec", WrapperKind::Option) => {
327                                return (WrapperKind::VecOption, inner_inner);
328                            }
329                            ("VecDeque", WrapperKind::Option) => {
330                                return (WrapperKind::VecDequeOption, inner_inner);
331                            }
332                            ("LinkedList", WrapperKind::Option) => {
333                                return (WrapperKind::LinkedListOption, inner_inner);
334                            }
335                            ("BinaryHeap", WrapperKind::Option) => {
336                                return (WrapperKind::BinaryHeapOption, inner_inner);
337                            }
338                            ("HashSet", WrapperKind::Option) => {
339                                return (WrapperKind::HashSetOption, inner_inner);
340                            }
341                            ("BTreeSet", WrapperKind::Option) => {
342                                return (WrapperKind::BTreeSetOption, inner_inner);
343                            }
344                            ("Result", WrapperKind::Option) => {
345                                return (WrapperKind::ResultOption, inner_inner);
346                            }
347                            ("HashMap", WrapperKind::Option) => {
348                                return (WrapperKind::HashMapOption, inner_inner);
349                            }
350                            // BTreeMapOption is handled in the map block (HashMap/BTreeMap)
351                            // std::sync variants (when inner is StdMutex/StdRwLock)
352                            ("Arc", WrapperKind::StdMutex) => {
353                                return (WrapperKind::StdArcMutex, inner_inner);
354                            }
355                            ("Arc", WrapperKind::StdRwLock) => {
356                                return (WrapperKind::StdArcRwLock, inner_inner);
357                            }
358                            // parking_lot variants (default - when inner is Mutex/RwLock without std::sync prefix)
359                            ("Arc", WrapperKind::Mutex) => {
360                                return (WrapperKind::ArcMutex, inner_inner);
361                            }
362                            ("Arc", WrapperKind::RwLock) => {
363                                return (WrapperKind::ArcRwLock, inner_inner);
364                            }
365                            // tokio::sync variants (when inner is TokioMutex/TokioRwLock)
366                            ("Arc", WrapperKind::TokioMutex) => {
367                                return (WrapperKind::TokioArcMutex, inner_inner);
368                            }
369                            ("Arc", WrapperKind::TokioRwLock) => {
370                                return (WrapperKind::TokioArcRwLock, inner_inner);
371                            }
372                            _ => {
373                                // Handle single-level containers
374                                // For Mutex and RwLock:
375                                // - If path contains std::sync, it's std::sync (StdMutex/StdRwLock)
376                                // - Otherwise, default to parking_lot (Mutex/RwLock)
377                                return match ident_str.as_str() {
378                                    "Option" => (WrapperKind::Option, Some(inner.clone())),
379                                    "Box" => (WrapperKind::Box, Some(inner.clone())),
380                                    "Rc" => (WrapperKind::Rc, Some(inner.clone())),
381                                    "Arc" => (WrapperKind::Arc, Some(inner.clone())),
382                                    "Vec" => (WrapperKind::Vec, Some(inner.clone())),
383                                    "HashSet" => (WrapperKind::HashSet, Some(inner.clone())),
384                                    "BTreeSet" => (WrapperKind::BTreeSet, Some(inner.clone())),
385                                    "VecDeque" => (WrapperKind::VecDeque, Some(inner.clone())),
386                                    "LinkedList" => (WrapperKind::LinkedList, Some(inner.clone())),
387                                    "BinaryHeap" => (WrapperKind::BinaryHeap, Some(inner.clone())),
388                                    "Result" => (WrapperKind::Result, Some(inner.clone())),
389                                    // For std::sync::Mutex and std::sync::RwLock, use Std variants
390                                    "Mutex" if is_std_sync => {
391                                        (WrapperKind::StdMutex, Some(inner.clone()))
392                                    }
393                                    "RwLock" if is_std_sync => {
394                                        (WrapperKind::StdRwLock, Some(inner.clone()))
395                                    }
396                                    // For tokio::sync::Mutex and tokio::sync::RwLock, use Tokio variants
397                                    "Mutex" if is_tokio_sync => {
398                                        (WrapperKind::TokioMutex, Some(inner.clone()))
399                                    }
400                                    "RwLock" if is_tokio_sync => {
401                                        (WrapperKind::TokioRwLock, Some(inner.clone()))
402                                    }
403                                    // Default: parking_lot (no std::sync or tokio::sync prefix)
404                                    "Mutex" => (WrapperKind::Mutex, Some(inner.clone())),
405                                    "RwLock" => (WrapperKind::RwLock, Some(inner.clone())),
406                                    "Weak" => (WrapperKind::Weak, Some(inner.clone())),
407                                    "Tagged" => (WrapperKind::Tagged, Some(inner.clone())),
408                                    "Cow" => (WrapperKind::Cow, Some(inner.clone())),
409                                    "AtomicPtr" if is_std_sync_atomic_type(&tp.path) => (WrapperKind::Atomic, None),
410                                    "Pin" => (WrapperKind::Pin, Some(inner.clone())),
411                                    "Cell" => (WrapperKind::Cell, Some(inner.clone())),
412                                    "RefCell" => (WrapperKind::RefCell, Some(inner.clone())),
413                                    "OnceCell" | "OnceLock" => (WrapperKind::OnceCell, Some(inner.clone())),
414                                    "Lazy" | "LazyLock" => (WrapperKind::Lazy, Some(inner.clone())),
415                                    "PhantomData" => (WrapperKind::PhantomData, Some(inner.clone())),
416                                    "Range" | "RangeInclusive" => (WrapperKind::Range, Some(inner.clone())),
417                                    _ => (WrapperKind::None, None),
418                                };
419                            }
420                        }
421                    }
422                }
423            }
424            // Handle atomic types with no angle bracket args (AtomicBool, AtomicI32, etc.)
425            if matches!(seg.arguments, PathArguments::None) {
426                if ident_str == "String" {
427                    return (WrapperKind::String, None);
428                }
429                if is_std_sync_atomic_type(&tp.path)
430                    && ATOMIC_TYPE_IDENTS.contains(&ident_str.as_str())
431                {
432                    return (WrapperKind::Atomic, None);
433                }
434            }
435        }
436    }
437    (WrapperKind::None, None)
438}
439
440/// Check if a field has the #[pin] attribute (pin_project pattern).
441fn field_has_pin_attr(field: &syn::Field) -> bool {
442    field.attrs.iter().any(|attr| {
443        attr.path().get_ident().map(|i| i == "pin").unwrap_or(false)
444    })
445}
446
447/// Check if a type is a Future (dyn Future, impl Future, or Box<dyn Future>).
448fn is_future_type(ty: &Type) -> bool {
449    use syn::{GenericArgument, PathArguments, TypeParamBound};
450
451    match ty {
452        Type::TraitObject(trait_obj) => trait_obj.bounds.iter().any(|b| {
453            if let TypeParamBound::Trait(t) = b {
454                t.path.segments.last()
455                    .map(|s| s.ident == "Future")
456                    .unwrap_or(false)
457            } else {
458                false
459            }
460        }),
461        Type::ImplTrait(impl_trait) => impl_trait.bounds.iter().any(|b| {
462            if let TypeParamBound::Trait(t) = b {
463                t.path.segments.last()
464                    .map(|s| s.ident == "Future")
465                    .unwrap_or(false)
466            } else {
467                false
468            }
469        }),
470        Type::Path(tp) => {
471            if let Some(seg) = tp.path.segments.last() {
472                match seg.ident.to_string().as_str() {
473                    "Box" | "Pin" => {
474                        if let PathArguments::AngleBracketed(args) = &seg.arguments {
475                            if let Some(GenericArgument::Type(inner)) = args.args.first() {
476                                return is_future_type(inner);
477                            }
478                        }
479                    }
480                    _ => {}
481                }
482            }
483            false
484        }
485        _ => false,
486    }
487}
488
489/// Extract Output type from Future trait bound (dyn Future<Output = T>, impl Future<Output = T>, etc.).
490fn extract_future_output(ty: &Type) -> Option<Type> {
491    use syn::{GenericArgument, PathArguments, TypeParamBound};
492
493    let bounds = match ty {
494        Type::TraitObject(t) => &t.bounds,
495        Type::ImplTrait(t) => &t.bounds,
496        Type::Path(tp) => {
497            if let Some(seg) = tp.path.segments.last() {
498                if matches!(seg.ident.to_string().as_str(), "Box" | "Pin") {
499                    if let PathArguments::AngleBracketed(args) = &seg.arguments {
500                        if let Some(GenericArgument::Type(inner)) = args.args.first() {
501                            return extract_future_output(inner);
502                        }
503                    }
504                }
505            }
506            return None;
507        }
508        _ => return None,
509    };
510
511    for bound in bounds {
512        if let TypeParamBound::Trait(trait_bound) = bound {
513            if let Some(seg) = trait_bound.path.segments.last() {
514                if seg.ident == "Future" {
515                    if let PathArguments::AngleBracketed(args) = &seg.arguments {
516                        for arg in &args.args {
517                            if let GenericArgument::AssocType(assoc) = arg {
518                                if assoc.ident == "Output" {
519                                    return Some(assoc.ty.clone());
520                                }
521                            }
522                        }
523                    }
524                }
525            }
526        }
527    }
528    None
529}
530
531/// For HashMap<K,V> or BTreeMap<K,V>, returns Some((key_ty, value_ty)).
532fn extract_map_key_value(ty: &Type) -> Option<(Type, Type)> {
533    use syn::{GenericArgument, PathArguments};
534
535    if let Type::Path(tp) = ty {
536        if let Some(seg) = tp.path.segments.last() {
537            let ident_str = seg.ident.to_string();
538            if ident_str == "HashMap" || ident_str == "BTreeMap" {
539                if let PathArguments::AngleBracketed(ab) = &seg.arguments {
540                    let args: Vec<_> = ab.args.iter().collect();
541                    if let (Some(key_arg), Some(value_arg)) = (args.get(0), args.get(1)) {
542                        if let (GenericArgument::Type(key_ty), GenericArgument::Type(value_ty)) =
543                            (key_arg, value_arg)
544                        {
545                            return Some((key_ty.clone(), value_ty.clone()));
546                        }
547                    }
548                }
549            }
550        }
551    }
552    None
553}
554
555fn to_snake_case(name: &str) -> String {
556    let mut out = String::new();
557    for (i, c) in name.chars().enumerate() {
558        if c.is_uppercase() {
559            if i != 0 {
560                out.push('_');
561            }
562            out.push(c.to_ascii_lowercase());
563        } else {
564            out.push(c);
565        }
566    }
567    out
568}
569
570/// Derive macro for generating simple keypath methods.
571/// 
572/// Generates one method per field: `StructName::field_name()` that returns a `Kp`.
573/// Intelligently handles wrapper types (Option, Vec, Box, Arc, etc.) to generate appropriate keypaths.
574/// 
575/// # Example
576/// 
577/// ```ignore
578/// #[derive(Kp)]
579/// struct Person {
580///     name: String,
581///     age: i32,
582///     email: Option<String>,
583///     addresses: Vec<String>,
584/// }
585/// 
586/// // Generates:
587/// // impl Person {
588/// //     pub fn name() -> Kp<...> { ... }
589/// //     pub fn age() -> Kp<...> { ... }
590/// //     pub fn email() -> Kp<...> { ... } // unwraps Option
591/// //     pub fn addresses() -> Kp<...> { ... } // accesses first element
592/// // }
593/// ```
594#[proc_macro_derive(Kp)]
595pub fn derive_keypaths(input: TokenStream) -> TokenStream {
596    let input = parse_macro_input!(input as DeriveInput);
597    let name = &input.ident;
598    let input_span = input.span();
599
600    let methods = match input.data {
601        Data::Struct(data_struct) => match data_struct.fields {
602            Fields::Named(fields_named) => {
603                let mut tokens = proc_macro2::TokenStream::new();
604
605                // Generate identity methods for the struct
606                tokens.extend(quote! {
607                    /// Returns a generic identity keypath for this type
608                    #[inline(always)]
609                    pub fn _identity<Root, MutRoot>() -> rust_key_paths::Kp<
610                        #name,
611                        #name,
612                        Root,
613                        Root,
614                        MutRoot,
615                        MutRoot,
616                        fn(Root) -> Option<Root>,
617                        fn(MutRoot) -> Option<MutRoot>,
618                    >
619                    where
620                        Root: std::borrow::Borrow<#name>,
621                        MutRoot: std::borrow::BorrowMut<#name>,
622                    {
623                        rust_key_paths::Kp::new(
624                            |r: Root| Some(r),
625                            |r: MutRoot| Some(r)
626                        )
627                    }
628
629                    // /// Returns a simple identity keypath for this type
630                    // #[inline(always)]
631                    // pub fn identity() -> rust_key_paths::KpType<'static, #name, #name> {
632                    //     rust_key_paths::Kp::new(
633                    //         |r: &#name| Some(r),
634                    //         |r: &mut #name| Some(r)
635                    //     )
636                    // }
637                });
638                
639                // When struct has #[pin] fields, generated code calls this.project() which must
640                // be provided by #[pin_project]. If missing, user gets: no method named `project`.
641
642                for field in fields_named.named.iter() {
643                    let field_ident = field.ident.as_ref().unwrap();
644                    let ty = &field.ty;
645                    // Centralized keypath method names – change here to adjust for all types
646                    let kp_fn = format_ident!("{}", field_ident);
647                    let kp_at_fn = format_ident!("{}_at", field_ident);
648
649                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
650
651                    // Override kind when field has #[pin] (pin_project pattern)
652                    let (kind, inner_ty) = if field_has_pin_attr(field) {
653                        let pinned_kind = if let Some(output_ty) = extract_future_output(ty) {
654                            if matches!(kind, WrapperKind::Box) {
655                                (WrapperKind::PinnedBoxFuture, Some(output_ty))
656                            } else {
657                                (WrapperKind::PinnedFuture, Some(output_ty))
658                            }
659                        } else if is_future_type(ty) {
660                            (WrapperKind::PinnedFuture, inner_ty.clone())
661                        } else {
662                            (WrapperKind::PinnedField, inner_ty.clone())
663                        };
664                        pinned_kind
665                    } else {
666                        (kind, inner_ty.clone())
667                    };
668
669                    match (kind, inner_ty) {
670                        (WrapperKind::Option, Some(inner_ty)) => {
671                            // For Option<T>, unwrap and access inner type
672                            tokens.extend(quote! {
673                                #[inline(always)]
674                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
675                                    rust_key_paths::Kp::new(
676                                        |root: &#name| root.#field_ident.as_ref(),
677                                        |root: &mut #name| root.#field_ident.as_mut(),
678                                    )
679                                }
680                            });
681                        }
682                        (WrapperKind::OptionBox, Some(inner_ty)) => {
683                            // For Option<Box<T>>, keypath to T: get returns Option<&T> via as_deref()
684                            tokens.extend(quote! {
685                                #[inline(always)]
686                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
687                                    rust_key_paths::Kp::new(
688                                        |root: &#name| root.#field_ident.as_deref(),
689                                        |root: &mut #name| root.#field_ident.as_deref_mut(),
690                                    )
691                                }
692                            });
693                        }
694                        (WrapperKind::OptionRc, Some(inner_ty)) => {
695                            // For Option<Rc<T>>, keypath to T: get returns Option<&T> via as_deref()
696                            // Setter: as_mut() gives Option<&mut Rc<T>>, and_then(Rc::get_mut) gives Option<&mut T>
697                            tokens.extend(quote! {
698                                #[inline(always)]
699                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
700                                    rust_key_paths::Kp::new(
701                                        |root: &#name| root.#field_ident.as_deref(),
702                                        |root: &mut #name| root.#field_ident.as_mut().and_then(std::rc::Rc::get_mut),
703                                    )
704                                }
705                            });
706                        }
707                        (WrapperKind::OptionArc, Some(inner_ty)) => {
708                            // For Option<Arc<T>>, keypath to T: get returns Option<&T> via as_deref()
709                            // Setter: as_mut() gives Option<&mut Arc<T>>, and_then(Arc::get_mut) gives Option<&mut T>
710                            tokens.extend(quote! {
711                                #[inline(always)]
712                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
713                                    rust_key_paths::Kp::new(
714                                        |root: &#name| root.#field_ident.as_deref(),
715                                        |root: &mut #name| root.#field_ident.as_mut().and_then(std::sync::Arc::get_mut),
716                                    )
717                                }
718                            });
719                        }
720                        (WrapperKind::OptionVecDeque, Some(_inner_ty))
721                        | (WrapperKind::OptionLinkedList, Some(_inner_ty))
722                        | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
723                        | (WrapperKind::OptionHashSet, Some(_inner_ty))
724                        | (WrapperKind::OptionBTreeSet, Some(_inner_ty))
725                        | (WrapperKind::OptionResult, Some(_inner_ty))
726                        | (WrapperKind::OptionBTreeMap, Some(_inner_ty)) => {
727                            // Keypath to the Option container (reference), like Vec/HashSet
728                            tokens.extend(quote! {
729                                #[inline(always)]
730                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
731                                    rust_key_paths::Kp::new(
732                                        |root: &#name| Some(&root.#field_ident),
733                                        |root: &mut #name| Some(&mut root.#field_ident),
734                                    )
735                                }
736                            });
737                        }
738                        (WrapperKind::Vec, Some(inner_ty)) => {
739                            tokens.extend(quote! {
740                                #[inline(always)]
741                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
742                                    rust_key_paths::Kp::new(
743                                        |root: &#name| Some(&root.#field_ident),
744                                        |root: &mut #name| Some(&mut root.#field_ident),
745                                    )
746                                }
747                                #[inline(always)]
748                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
749                                    rust_key_paths::Kp::new(
750                                        Box::new(move |root: &#name| root.#field_ident.get(index)),
751                                        Box::new(move |root: &mut #name| root.#field_ident.get_mut(index)),
752                                    )
753                                }
754                            });
755                        }
756                        (WrapperKind::HashMap, Some(inner_ty)) => {
757                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
758                                tokens.extend(quote! {
759                                    #[inline(always)]
760                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
761                                        rust_key_paths::Kp::new(
762                                            |root: &#name| Some(&root.#field_ident),
763                                            |root: &mut #name| Some(&mut root.#field_ident),
764                                        )
765                                    }
766                                    #[inline(always)]
767                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
768                                    where
769                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
770                                    {
771                                        let key2 = key.clone();
772                                        rust_key_paths::Kp::new(
773                                            Box::new(move |root: &#name| root.#field_ident.get(&key)),
774                                            Box::new(move |root: &mut #name| root.#field_ident.get_mut(&key2)),
775                                        )
776                                    }
777                                });
778                            } else {
779                                tokens.extend(quote! {
780                                    #[inline(always)]
781                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
782                                        rust_key_paths::Kp::new(
783                                            |root: &#name| Some(&root.#field_ident),
784                                            |root: &mut #name| Some(&mut root.#field_ident),
785                                        )
786                                    }
787                                });
788                            }
789                        }
790                        (WrapperKind::BTreeMap, Some(inner_ty)) | (WrapperKind::BTreeMapOption, Some(inner_ty)) => {
791                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
792                                tokens.extend(quote! {
793                                    #[inline(always)]
794                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
795                                        rust_key_paths::Kp::new(
796                                            |root: &#name| Some(&root.#field_ident),
797                                            |root: &mut #name| Some(&mut root.#field_ident),
798                                        )
799                                    }
800                                    #[inline(always)]
801                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
802                                    where
803                                        #key_ty: Clone + Ord + 'static,
804                                    {
805                                        let key2 = key.clone();
806                                        rust_key_paths::Kp::new(
807                                            Box::new(move |root: &#name| root.#field_ident.get(&key)),
808                                            Box::new(move |root: &mut #name| root.#field_ident.get_mut(&key2)),
809                                        )
810                                    }
811                                });
812                            } else {
813                                tokens.extend(quote! {
814                                    #[inline(always)]
815                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
816                                        rust_key_paths::Kp::new(
817                                            |root: &#name| Some(&root.#field_ident),
818                                            |root: &mut #name| Some(&mut root.#field_ident),
819                                        )
820                                    }
821                                });
822                            }
823                        }
824                        (WrapperKind::Box, Some(inner_ty)) => {
825                            // For Box<T>, deref to inner type (returns &T / &mut T, not &Box<T>)
826                            tokens.extend(quote! {
827                                #[inline(always)]
828                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
829                                    rust_key_paths::Kp::new(
830                                        |root: &#name| Some(&*root.#field_ident),
831                                        |root: &mut #name| Some(&mut *root.#field_ident),
832                                    )
833                                }
834                            });
835                        }
836                        (WrapperKind::BoxOption, Some(inner_ty)) => {
837                            // For Box<Option<T>>, keypath to T: deref Box to Option<T>, then Option::as_ref/as_mut
838                            tokens.extend(quote! {
839                                #[inline(always)]
840                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
841                                    rust_key_paths::Kp::new(
842                                        |root: &#name| (&*root.#field_ident).as_ref(),
843                                        |root: &mut #name| (&mut *root.#field_ident).as_mut(),
844                                    )
845                                }
846                            });
847                        }
848                        (WrapperKind::RcOption, Some(inner_ty)) => {
849                            // For Rc<Option<T>>, keypath to T: deref Rc to &Option<T>, then Option::as_ref; set = Rc::get_mut then as_mut
850                            tokens.extend(quote! {
851                                #[inline(always)]
852                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
853                                    rust_key_paths::Kp::new(
854                                        |root: &#name| (&*root.#field_ident).as_ref(),
855                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#field_ident).and_then(std::option::Option::as_mut),
856                                    )
857                                }
858                            });
859                        }
860                        (WrapperKind::ArcOption, Some(inner_ty)) => {
861                            // For Arc<Option<T>>, keypath to T: deref Arc to &Option<T>, then Option::as_ref; set = Arc::get_mut then as_mut
862                            tokens.extend(quote! {
863                                #[inline(always)]
864                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
865                                    rust_key_paths::Kp::new(
866                                        |root: &#name| (&*root.#field_ident).as_ref(),
867                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#field_ident).and_then(std::option::Option::as_mut),
868                                    )
869                                }
870                            });
871                        }
872                        (WrapperKind::Pin, Some(inner_ty)) => {
873                            let kp_inner_fn = format_ident!("{}_inner", field_ident);
874                            tokens.extend(quote! {
875                                #[inline(always)]
876                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
877                                    rust_key_paths::Kp::new(
878                                        |root: &#name| Some(&root.#field_ident),
879                                        |root: &mut #name| Some(&mut root.#field_ident),
880                                    )
881                                }
882                                #[inline(always)]
883                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
884                                where #inner_ty: std::marker::Unpin
885                                {
886                                    rust_key_paths::Kp::new(
887                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#field_ident).get_ref()),
888                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#field_ident).get_mut()),
889                                    )
890                                }
891                            });
892                        }
893                        (WrapperKind::PinBox, Some(inner_ty)) => {
894                            let kp_inner_fn = format_ident!("{}_inner", field_ident);
895                            tokens.extend(quote! {
896                                #[inline(always)]
897                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
898                                    rust_key_paths::Kp::new(
899                                        |root: &#name| Some(&root.#field_ident),
900                                        |root: &mut #name| Some(&mut root.#field_ident),
901                                    )
902                                }
903                                #[inline(always)]
904                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
905                                where #inner_ty: std::marker::Unpin
906                                {
907                                    // Pin::as_ref on Pin<Box<T>> returns Pin<&T> (Box Deref target), so get_ref() already gives &T
908                                    rust_key_paths::Kp::new(
909                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#field_ident).get_ref()),
910                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#field_ident).get_mut()),
911                                    )
912                                }
913                            });
914                        }
915                        (WrapperKind::PinnedField, _) => {
916                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
917                            tokens.extend(quote! {
918                                #[inline(always)]
919                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
920                                    rust_key_paths::Kp::new(
921                                        |root: &#name| Some(&root.#field_ident),
922                                        |root: &mut #name| Some(&mut root.#field_ident),
923                                    )
924                                }
925                                /// Pinned projection for #[pin] field. Requires #[pin_project] on struct.
926                                #[inline(always)]
927                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
928                                    this.project().#field_ident
929                                }
930                            });
931                        }
932                        (WrapperKind::PinnedFuture, _) => {
933                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
934                            let kp_await_fn = format_ident!("{}_await", field_ident);
935                            let kp_pin_future_fn = format_ident!("{}_pin_future_kp", field_ident);
936                            let output_ty = quote! { <#ty as std::future::Future>::Output };
937                            tokens.extend(quote! {
938                                #[inline(always)]
939                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
940                                    rust_key_paths::Kp::new(
941                                        |root: &#name| Some(&root.#field_ident),
942                                        |root: &mut #name| Some(&mut root.#field_ident),
943                                    )
944                                }
945                                /// Pinned projection for #[pin] Future field. Requires #[pin_project] on struct.
946                                #[inline(always)]
947                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
948                                    this.project().#field_ident
949                                }
950                                /// Poll the pinned future. Requires #[pin_project] on struct.
951                                pub async fn #kp_await_fn(this: std::pin::Pin<&mut #name>) -> Option<#output_ty>
952                                where #ty: std::future::Future
953                                {
954                                    use std::future::Future;
955                                    Some(this.project().#field_ident.await)
956                                }
957                                /// Keypath for [rust_key_paths::Kp::then_pin_future]. Composable pin future await.
958                                #[inline(always)]
959                                pub fn #kp_pin_future_fn() -> impl rust_key_paths::pin::PinFutureAwaitLike<#name, #output_ty> {
960                                    rust_key_paths::pin_future_await_kp!(#name, #kp_await_fn -> #output_ty)
961                                }
962                            });
963                        }
964                        (WrapperKind::PinnedBoxFuture, Some(output_ty)) => {
965                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
966                            let kp_await_fn = format_ident!("{}_await", field_ident);
967                            let kp_pin_future_fn = format_ident!("{}_pin_future_kp", field_ident);
968                            tokens.extend(quote! {
969                                #[inline(always)]
970                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
971                                    rust_key_paths::Kp::new(
972                                        |root: &#name| Some(&root.#field_ident),
973                                        |root: &mut #name| Some(&mut root.#field_ident),
974                                    )
975                                }
976                                /// Pinned projection for #[pin] Box<dyn Future> field. Requires #[pin_project] on struct.
977                                #[inline(always)]
978                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
979                                    this.project().#field_ident
980                                }
981                                /// Poll the pinned boxed future. Requires #[pin_project] on struct.
982                                pub async fn #kp_await_fn(this: std::pin::Pin<&mut #name>) -> Option<#output_ty> {
983                                    Some(this.project().#field_ident.await)
984                                }
985                                /// Keypath for [rust_key_paths::Kp::then_pin_future]. Composable pin future await.
986                                #[inline(always)]
987                                pub fn #kp_pin_future_fn() -> impl rust_key_paths::pin::PinFutureAwaitLike<#name, #output_ty> {
988                                    rust_key_paths::pin_future_await_kp!(#name, #kp_await_fn -> #output_ty)
989                                }
990                            });
991                        }
992                        (WrapperKind::Rc, Some(inner_ty)) => {
993                            // For Rc<T>, deref to inner type (returns &T; get_mut when uniquely owned)
994                            tokens.extend(quote! {
995                                #[inline(always)]
996                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
997                                    rust_key_paths::Kp::new(
998                                        |root: &#name| Some(root.#field_ident.as_ref()),
999                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#field_ident),
1000                                    )
1001                                }
1002                            });
1003                        }
1004                        (WrapperKind::Arc, Some(inner_ty)) => {
1005                            // For Arc<T>, deref to inner type (returns &T; get_mut when uniquely owned)
1006                            tokens.extend(quote! {
1007                                #[inline(always)]
1008                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1009                                    rust_key_paths::Kp::new(
1010                                        |root: &#name| Some(root.#field_ident.as_ref()),
1011                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#field_ident),
1012                                    )
1013                                }
1014                            });
1015                        }
1016                        (WrapperKind::Cow, Some(inner_ty)) => {
1017                            // For Cow<'_, B>, deref to inner type (as_ref/to_mut)
1018                            tokens.extend(quote! {
1019                                #[inline(always)]
1020                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1021                                    rust_key_paths::Kp::new(
1022                                        |root: &#name| Some(root.#field_ident.as_ref()),
1023                                        |root: &mut #name| Some(root.#field_ident.to_mut()),
1024                                    )
1025                                }
1026                            });
1027                        }
1028                        
1029                        (WrapperKind::OptionCow, Some(inner_ty)) => {
1030                            // For Option<Cow<'_, B>>
1031                            tokens.extend(quote! {
1032                                #[inline(always)]
1033                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1034                                    rust_key_paths::Kp::new(
1035                                        |root: &#name| root.#field_ident.as_ref().map(|c| c.as_ref()),
1036                                        |root: &mut #name| root.#field_ident.as_mut().map(|c| c.to_mut()),
1037                                    )
1038                                }
1039                            });
1040                        }
1041                        (WrapperKind::OptionTagged, Some(inner_ty)) => {
1042                            // For Option<Tagged<Tag, T>> - Tagged implements Deref/DerefMut
1043                            tokens.extend(quote! {
1044                                #[inline(always)]
1045                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1046                                    rust_key_paths::Kp::new(
1047                                        |root: &#name| root.#field_ident.as_ref().map(|t| std::ops::Deref::deref(t)),
1048                                        |root: &mut #name| root.#field_ident.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
1049                                    )
1050                                }
1051                            });
1052                        }
1053                        (WrapperKind::OptionReference, Some(inner_ty)) => {
1054                            // For Option<&T>, Option<&str>, Option<&[T]> - read-only, setter returns None
1055                            tokens.extend(quote! {
1056                                #[inline(always)]
1057                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1058                                    rust_key_paths::Kp::new(
1059                                        |root: &#name| root.#field_ident.as_ref(),
1060                                        |_root: &mut #name| None,
1061                                    )
1062                                }
1063                            });
1064                        }
1065                        (WrapperKind::HashSet, Some(inner_ty)) | (WrapperKind::HashSetOption, Some(inner_ty)) => {
1066                            let kp_at_fn = format_ident!("{}_at", field_ident);
1067
1068                            tokens.extend(quote! {
1069                                #[inline(always)]
1070                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1071                                    rust_key_paths::Kp::new(
1072                                        |root: &#name| Some(&root.#field_ident),
1073                                        |root: &mut #name| Some(&mut root.#field_ident),
1074                                    )
1075                                }
1076
1077                                /// _at: check if element exists and get reference.
1078                                /// HashSet does not allow mutable element access (would break hash invariant).
1079                                #[inline(always)]
1080                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1081                                where
1082                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
1083                                {
1084                                    rust_key_paths::Kp::new(
1085                                        Box::new(move |root: &#name| root.#field_ident.get(&key)),
1086                                        Box::new(move |_root: &mut #name| None),
1087                                    )
1088                                }
1089                            });
1090                        }
1091                        (WrapperKind::BTreeSet, Some(inner_ty)) | (WrapperKind::BTreeSetOption, Some(inner_ty)) => {
1092                            let kp_at_fn = format_ident!("{}_at", field_ident);
1093
1094                            tokens.extend(quote! {
1095                                #[inline(always)]
1096                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1097                                    rust_key_paths::Kp::new(
1098                                        |root: &#name| Some(&root.#field_ident),
1099                                        |root: &mut #name| Some(&mut root.#field_ident),
1100                                    )
1101                                }
1102
1103                                /// _at: check if element exists and get reference.
1104                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
1105                                #[inline(always)]
1106                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1107                                where
1108                                    #inner_ty: Clone + Ord + 'static,
1109                                {
1110                                    rust_key_paths::Kp::new(
1111                                        Box::new(move |root: &#name| root.#field_ident.get(&key)),
1112                                        Box::new(move |_root: &mut #name| None),
1113                                    )
1114                                }
1115                            });
1116                        }
1117                        (WrapperKind::VecDeque, Some(inner_ty)) | (WrapperKind::VecDequeOption, Some(inner_ty)) => {
1118                            tokens.extend(quote! {
1119                                #[inline(always)]
1120                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1121                                    rust_key_paths::Kp::new(
1122                                        |root: &#name| Some(&root.#field_ident),
1123                                        |root: &mut #name| Some(&mut root.#field_ident),
1124                                    )
1125                                }
1126                                #[inline(always)]
1127                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1128                                    rust_key_paths::Kp::new(
1129                                        Box::new(move |root: &#name| root.#field_ident.get(index)),
1130                                        Box::new(move |root: &mut #name| root.#field_ident.get_mut(index)),
1131                                    )
1132                                }
1133                            });
1134                        }
1135                        (WrapperKind::LinkedList, Some(_inner_ty)) | (WrapperKind::LinkedListOption, Some(_inner_ty)) => {
1136                            tokens.extend(quote! {
1137                                #[inline(always)]
1138                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1139                                    rust_key_paths::Kp::new(
1140                                        |root: &#name| Some(&root.#field_ident),
1141                                        |root: &mut #name| Some(&mut root.#field_ident),
1142                                    )
1143                                }
1144                            });
1145                        }
1146                        (WrapperKind::BinaryHeap, Some(_inner_ty)) | (WrapperKind::BinaryHeapOption, Some(_inner_ty)) => {
1147                            tokens.extend(quote! {
1148                                #[inline(always)]
1149                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1150                                    rust_key_paths::Kp::new(
1151                                        |root: &#name| Some(&root.#field_ident),
1152                                        |root: &mut #name| Some(&mut root.#field_ident),
1153                                    )
1154                                }
1155                            });
1156                        }
1157                        (WrapperKind::Result, Some(inner_ty)) => {
1158                            // For Result<T, E>, access Ok value
1159                            tokens.extend(quote! {
1160                                #[inline(always)]
1161                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1162                                    rust_key_paths::Kp::new(
1163                                        |root: &#name| root.#field_ident.as_ref().ok(),
1164                                        |root: &mut #name| root.#field_ident.as_mut().ok(),
1165                                    )
1166                                }
1167                            });
1168                        }
1169                        (WrapperKind::StdArcMutex, Some(inner_ty)) => {
1170                            // For Arc<std::sync::Mutex<T>>
1171                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1172                            tokens.extend(quote! {
1173                                #[inline(always)]
1174                                    pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1175                                    rust_key_paths::Kp::new(
1176                                        |root: &#name| Some(&root.#field_ident),
1177                                        |root: &mut #name| Some(&mut root.#field_ident),
1178                                    )
1179                                }
1180                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcMutexFor<#name, #ty, #inner_ty> {
1181                                    rust_key_paths::lock::LockKp::new(
1182                                        rust_key_paths::Kp::new(
1183                                            |root: &#name| Some(&root.#field_ident),
1184                                            |root: &mut #name| Some(&mut root.#field_ident),
1185                                        ),
1186                                        rust_key_paths::lock::ArcMutexAccess::new(),
1187                                        rust_key_paths::Kp::new(
1188                                            |v: &#inner_ty| Some(v),
1189                                            |v: &mut #inner_ty| Some(v),
1190                                        ),
1191                                    )
1192                                }
1193                            });
1194                        }
1195                        (WrapperKind::StdArcRwLock, Some(inner_ty)) => {
1196                            // For Arc<std::sync::RwLock<T>>
1197                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1198                            tokens.extend(quote! {
1199                                #[inline(always)]
1200                                    pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1201                                    rust_key_paths::Kp::new(
1202                                        |root: &#name| Some(&root.#field_ident),
1203                                        |root: &mut #name| Some(&mut root.#field_ident),
1204                                    )
1205                                }
1206                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, #ty, #inner_ty> {
1207                                    rust_key_paths::lock::LockKp::new(
1208                                        rust_key_paths::Kp::new(
1209                                            |root: &#name| Some(&root.#field_ident),
1210                                            |root: &mut #name| Some(&mut root.#field_ident),
1211                                        ),
1212                                        rust_key_paths::lock::ArcRwLockAccess::new(),
1213                                        rust_key_paths::Kp::new(
1214                                            |v: &#inner_ty| Some(v),
1215                                            |v: &mut #inner_ty| Some(v),
1216                                        ),
1217                                    )
1218                                }
1219                            });
1220                        }
1221                        (WrapperKind::ArcRwLock, Some(inner_ty)) => {
1222                            // For Arc<parking_lot::RwLock<T>> (requires rust-key-paths "parking_lot" feature)
1223                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1224                            tokens.extend(quote! {
1225                                #[inline(always)]
1226                                pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1227                                    rust_key_paths::Kp::new(
1228                                        |root: &#name| Some(&root.#field_ident),
1229                                        |root: &mut #name| Some(&mut root.#field_ident),
1230                                    )
1231                                }
1232                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, #ty, #inner_ty> {
1233                                    rust_key_paths::lock::LockKp::new(
1234                                        rust_key_paths::Kp::new(
1235                                            |root: &#name| Some(&root.#field_ident),
1236                                            |root: &mut #name| Some(&mut root.#field_ident),
1237                                        ),
1238                                        rust_key_paths::lock::ParkingLotRwLockAccess::new(),
1239                                        rust_key_paths::Kp::new(
1240                                            |v: &#inner_ty| Some(v),
1241                                            |v: &mut #inner_ty| Some(v),
1242                                        ),
1243                                    )
1244                                }
1245                            });
1246                        }
1247                        (WrapperKind::ArcMutex, Some(inner_ty)) => {
1248                            // For Arc<parking_lot::Mutex<T>> (requires rust-key-paths "parking_lot" feature)
1249                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1250                            tokens.extend(quote! {
1251                                #[inline(always)]
1252                                pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1253                                    rust_key_paths::Kp::new(
1254                                        |root: &#name| Some(&root.#field_ident),
1255                                        |root: &mut #name| Some(&mut root.#field_ident),
1256                                    )
1257                                }
1258                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, #ty, #inner_ty> {
1259                                    rust_key_paths::lock::LockKp::new(
1260                                        rust_key_paths::Kp::new(
1261                                            |root: &#name| Some(&root.#field_ident),
1262                                            |root: &mut #name| Some(&mut root.#field_ident),
1263                                        ),
1264                                        rust_key_paths::lock::ParkingLotMutexAccess::new(),
1265                                        rust_key_paths::Kp::new(
1266                                            |v: &#inner_ty| Some(v),
1267                                            |v: &mut #inner_ty| Some(v),
1268                                        ),
1269                                    )
1270                                }
1271                            });
1272                        }
1273                        (WrapperKind::Mutex, Some(_inner_ty))
1274                        | (WrapperKind::StdMutex, Some(_inner_ty)) => {
1275                            // For Mutex<T>, return keypath to container
1276                            tokens.extend(quote! {
1277                                #[inline(always)]
1278                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1279                                    rust_key_paths::Kp::new(
1280                                        |root: &#name| Some(&root.#field_ident),
1281                                        |root: &mut #name| Some(&mut root.#field_ident),
1282                                    )
1283                                }
1284                            });
1285                        }
1286                        (WrapperKind::RwLock, Some(_inner_ty))
1287                        | (WrapperKind::StdRwLock, Some(_inner_ty)) => {
1288                            // For RwLock<T>, return keypath to container
1289                            tokens.extend(quote! {
1290                                #[inline(always)]
1291                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1292                                    rust_key_paths::Kp::new(
1293                                        |root: &#name| Some(&root.#field_ident),
1294                                        |root: &mut #name| Some(&mut root.#field_ident),
1295                                    )
1296                                }
1297                            });
1298                        }
1299                        (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
1300                            let kp_async_fn = format_ident!("{}_kp", field_ident);
1301                            tokens.extend(quote! {
1302                                #[inline(always)]
1303                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1304                                    rust_key_paths::Kp::new(
1305                                        |root: &#name| Some(&root.#field_ident),
1306                                        |root: &mut #name| Some(&mut root.#field_ident),
1307                                    )
1308                                }
1309                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #ty, #inner_ty> {
1310                                    rust_key_paths::async_lock::AsyncLockKp::new(
1311                                        rust_key_paths::Kp::new(
1312                                            |root: &#name| Some(&root.#field_ident),
1313                                            |root: &mut #name| Some(&mut root.#field_ident),
1314                                        ),
1315                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
1316                                        rust_key_paths::Kp::new(
1317                                            |v: &#inner_ty| Some(v),
1318                                            |v: &mut #inner_ty| Some(v),
1319                                        ),
1320                                    )
1321                                }
1322                            });
1323                        }
1324                        (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
1325                            let kp_async_fn = format_ident!("{}_kp", field_ident);
1326                            tokens.extend(quote! {
1327                                #[inline(always)]
1328                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1329                                    rust_key_paths::Kp::new(
1330                                        |root: &#name| Some(&root.#field_ident),
1331                                        |root: &mut #name| Some(&mut root.#field_ident),
1332                                    )
1333                                }
1334                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #ty, #inner_ty> {
1335                                    rust_key_paths::async_lock::AsyncLockKp::new(
1336                                        rust_key_paths::Kp::new(
1337                                            |root: &#name| Some(&root.#field_ident),
1338                                            |root: &mut #name| Some(&mut root.#field_ident),
1339                                        ),
1340                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
1341                                        rust_key_paths::Kp::new(
1342                                            |v: &#inner_ty| Some(v),
1343                                            |v: &mut #inner_ty| Some(v),
1344                                        ),
1345                                    )
1346                                }
1347                            });
1348                        }
1349                        (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
1350                            let kp_async_fn = format_ident!("{}_kp", field_ident);
1351                            tokens.extend(quote! {
1352                                #[inline(always)]
1353                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1354                                    rust_key_paths::Kp::new(
1355                                        |root: &#name| Some(&root.#field_ident),
1356                                        |root: &mut #name| Some(&mut root.#field_ident),
1357                                    )
1358                                }
1359                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
1360                                    rust_key_paths::async_lock::AsyncLockKp::new(
1361                                        rust_key_paths::Kp::new(
1362                                            |root: &#name| root.#field_ident.as_ref(),
1363                                            |root: &mut #name| root.#field_ident.as_mut(),
1364                                        ),
1365                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
1366                                        rust_key_paths::Kp::new(
1367                                            |v: &#inner_ty| Some(v),
1368                                            |v: &mut #inner_ty| Some(v),
1369                                        ),
1370                                    )
1371                                }
1372                            });
1373                        }
1374                        (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
1375                            let kp_async_fn = format_ident!("{}_kp", field_ident);
1376                            tokens.extend(quote! {
1377                                #[inline(always)]
1378                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1379                                    rust_key_paths::Kp::new(
1380                                        |root: &#name| Some(&root.#field_ident),
1381                                        |root: &mut #name| Some(&mut root.#field_ident),
1382                                    )
1383                                }
1384                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
1385                                    rust_key_paths::async_lock::AsyncLockKp::new(
1386                                        rust_key_paths::Kp::new(
1387                                            |root: &#name| root.#field_ident.as_ref(),
1388                                            |root: &mut #name| root.#field_ident.as_mut(),
1389                                        ),
1390                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
1391                                        rust_key_paths::Kp::new(
1392                                            |v: &#inner_ty| Some(v),
1393                                            |v: &mut #inner_ty| Some(v),
1394                                        ),
1395                                    )
1396                                }
1397                            });
1398                        }
1399                        (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
1400                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1401                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1402                            tokens.extend(quote! {
1403                                #[inline(always)]
1404                                    pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1405                                    rust_key_paths::Kp::new(
1406                                        |root: &#name| Some(&root.#field_ident),
1407                                        |root: &mut #name| Some(&mut root.#field_ident),
1408                                    )
1409                                }
1410                                // pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::Mutex<#inner_ty>>> {
1411                                //     rust_key_paths::Kp::new(
1412                                //         |root: &#name| root.#field_ident.as_ref(),
1413                                //         |root: &mut #name| root.#field_ident.as_mut(),
1414                                //     )
1415                                // }
1416                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcMutexFor<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, #inner_ty> {
1417                                    rust_key_paths::lock::LockKp::new(
1418                                        rust_key_paths::Kp::new(
1419                                            |root: &#name| root.#field_ident.as_ref(),
1420                                            |root: &mut #name| root.#field_ident.as_mut(),
1421                                        ),
1422                                        rust_key_paths::lock::ArcMutexAccess::new(),
1423                                        rust_key_paths::Kp::new(
1424                                            |v: &#inner_ty| Some(v),
1425                                            |v: &mut #inner_ty| Some(v),
1426                                        ),
1427                                    )
1428                                }
1429                            });
1430                        }
1431                        (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
1432                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1433                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1434                            tokens.extend(quote! {
1435                                #[inline(always)]
1436                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1437                                    rust_key_paths::Kp::new(
1438                                        |root: &#name| Some(&root.#field_ident),
1439                                        |root: &mut #name| Some(&mut root.#field_ident),
1440                                    )
1441                                }
1442                                // pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>> {
1443                                //     rust_key_paths::Kp::new(
1444                                //         |root: &#name| root.#field_ident.as_ref(),
1445                                //         |root: &mut #name| root.#field_ident.as_mut(),
1446                                //     )
1447                                // }
1448                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, #inner_ty> {
1449                                    rust_key_paths::lock::LockKp::new(
1450                                        rust_key_paths::Kp::new(
1451                                            |root: &#name| root.#field_ident.as_ref(),
1452                                            |root: &mut #name| root.#field_ident.as_mut(),
1453                                        ),
1454                                        rust_key_paths::lock::ParkingLotMutexAccess::new(),
1455                                        rust_key_paths::Kp::new(
1456                                            |v: &#inner_ty| Some(v),
1457                                            |v: &mut #inner_ty| Some(v),
1458                                        ),
1459                                    )
1460                                }
1461                            });
1462                        }
1463                        (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
1464                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1465                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1466                            tokens.extend(quote! {
1467                                #[inline(always)]
1468                                    pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1469                                    rust_key_paths::Kp::new(
1470                                        |root: &#name| Some(&root.#field_ident),
1471                                        |root: &mut #name| Some(&mut root.#field_ident),
1472                                    )
1473                                }
1474                                // pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::RwLock<#inner_ty>>> {
1475                                //     rust_key_paths::Kp::new(
1476                                //         |root: &#name| root.#field_ident.as_ref(),
1477                                //         |root: &mut #name| root.#field_ident.as_mut(),
1478                                //     )
1479                                // }
1480                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, #inner_ty> {
1481                                    rust_key_paths::lock::LockKp::new(
1482                                        rust_key_paths::Kp::new(
1483                                            |root: &#name| root.#field_ident.as_ref(),
1484                                            |root: &mut #name| root.#field_ident.as_mut(),
1485                                        ),
1486                                        rust_key_paths::lock::ArcRwLockAccess::new(),
1487                                        rust_key_paths::Kp::new(
1488                                            |v: &#inner_ty| Some(v),
1489                                            |v: &mut #inner_ty| Some(v),
1490                                        ),
1491                                    )
1492                                }
1493                            });
1494                        }
1495                        (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
1496                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1497                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1498                            tokens.extend(quote! {
1499                                #[inline(always)]
1500                                    pub fn #kp_lock_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1501                                    rust_key_paths::Kp::new(
1502                                        |root: &#name| Some(&root.#field_ident),
1503                                        |root: &mut #name| Some(&mut root.#field_ident),
1504                                    )
1505                                }
1506                                // pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>> {
1507                                //     rust_key_paths::Kp::new(
1508                                //         |root: &#name| root.#field_ident.as_ref(),
1509                                //         |root: &mut #name| root.#field_ident.as_mut(),
1510                                //     )
1511                                // }
1512                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, #inner_ty> {
1513                                    rust_key_paths::lock::LockKp::new(
1514                                        rust_key_paths::Kp::new(
1515                                            |root: &#name| root.#field_ident.as_ref(),
1516                                            |root: &mut #name| root.#field_ident.as_mut(),
1517                                        ),
1518                                        rust_key_paths::lock::ParkingLotRwLockAccess::new(),
1519                                        rust_key_paths::Kp::new(
1520                                            |v: &#inner_ty| Some(v),
1521                                            |v: &mut #inner_ty| Some(v),
1522                                        ),
1523                                    )
1524                                }
1525                            });
1526                        }
1527                        (WrapperKind::OptionStdMutex, Some(inner_ty))
1528                        | (WrapperKind::OptionMutex, Some(inner_ty)) => {
1529                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1530                            tokens.extend(quote! {
1531                                #[inline(always)]
1532                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1533                                    rust_key_paths::Kp::new(
1534                                        |root: &#name| Some(&root.#field_ident),
1535                                        |root: &mut #name| Some(&mut root.#field_ident),
1536                                    )
1537                                }
1538                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Mutex<#inner_ty>> {
1539                                    rust_key_paths::Kp::new(
1540                                        |root: &#name| root.#field_ident.as_ref(),
1541                                        |root: &mut #name| root.#field_ident.as_mut(),
1542                                    )
1543                                }
1544                            });
1545                        }
1546                        (WrapperKind::OptionStdRwLock, Some(inner_ty))
1547                        | (WrapperKind::OptionRwLock, Some(inner_ty)) => {
1548                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1549                            tokens.extend(quote! {
1550                                #[inline(always)]
1551                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1552                                    rust_key_paths::Kp::new(
1553                                        |root: &#name| Some(&root.#field_ident),
1554                                        |root: &mut #name| Some(&mut root.#field_ident),
1555                                    )
1556                                }
1557                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::RwLock<#inner_ty>> {
1558                                    rust_key_paths::Kp::new(
1559                                        |root: &#name| root.#field_ident.as_ref(),
1560                                        |root: &mut #name| root.#field_ident.as_mut(),
1561                                    )
1562                                }
1563                            });
1564                        }
1565                        (WrapperKind::Weak, Some(_inner_ty)) => {
1566                            // For Weak<T>, return keypath to container
1567                            tokens.extend(quote! {
1568                                #[inline(always)]
1569                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1570                                    rust_key_paths::Kp::new(
1571                                        |root: &#name| Some(&root.#field_ident),
1572                                        |_root: &mut #name| None, // Weak doesn't support mutable access
1573                                    )
1574                                }
1575                            });
1576                        }
1577                        (WrapperKind::Atomic, None | Some(_)) => {
1578                            // For atomic types: return keypath to the atomic (user calls .load()/.store())
1579                            tokens.extend(quote! {
1580                                #[inline(always)]
1581                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1582                                    rust_key_paths::Kp::new(
1583                                        |root: &#name| Some(&root.#field_ident),
1584                                        |root: &mut #name| Some(&mut root.#field_ident),
1585                                    )
1586                                }
1587                            });
1588                        }
1589                        (WrapperKind::OptionAtomic, Some(inner_ty)) => {
1590                            tokens.extend(quote! {
1591                                #[inline(always)]
1592                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1593                                    rust_key_paths::Kp::new(
1594                                        |root: &#name| root.#field_ident.as_ref(),
1595                                        |root: &mut #name| root.#field_ident.as_mut(),
1596                                    )
1597                                }
1598                            });
1599                        }
1600                        (WrapperKind::String, None) => {
1601                            tokens.extend(quote! {
1602                                #[inline(always)]
1603                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1604                                    rust_key_paths::Kp::new(
1605                                        |root: &#name| Some(&root.#field_ident),
1606                                        |root: &mut #name| Some(&mut root.#field_ident),
1607                                    )
1608                                }
1609                            });
1610                        }
1611                        (WrapperKind::OptionString, None) => {
1612                            tokens.extend(quote! {
1613                                #[inline(always)]
1614                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, std::string::String> {
1615                                    rust_key_paths::Kp::new(
1616                                        |root: &#name| root.#field_ident.as_ref(),
1617                                        |root: &mut #name| root.#field_ident.as_mut(),
1618                                    )
1619                                }
1620                            });
1621                        }
1622                        (WrapperKind::Cell, Some(_inner_ty)) => {
1623                            tokens.extend(quote! {
1624                                #[inline(always)]
1625                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1626                                    rust_key_paths::Kp::new(
1627                                        |root: &#name| Some(&root.#field_ident),
1628                                        |root: &mut #name| Some(&mut root.#field_ident),
1629                                    )
1630                                }
1631                            });
1632                        }
1633                        (WrapperKind::RefCell, Some(_inner_ty)) => {
1634                            tokens.extend(quote! {
1635                                #[inline(always)]
1636                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1637                                    rust_key_paths::Kp::new(
1638                                        |root: &#name| Some(&root.#field_ident),
1639                                        |root: &mut #name| Some(&mut root.#field_ident),
1640                                    )
1641                                }
1642                            });
1643                        }
1644                        (WrapperKind::OnceCell, Some(inner_ty)) => {
1645                            // OnceLock/OnceCell: keypath to inner value; get = .get() -> Option<&T>, set = None
1646                            tokens.extend(quote! {
1647                                #[inline(always)]
1648                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1649                                    rust_key_paths::Kp::new(
1650                                        |root: &#name| root.#field_ident.get(),
1651                                        |_root: &mut #name| None,
1652                                    )
1653                                }
1654                            });
1655                        }
1656                        (WrapperKind::Lazy, Some(inner_ty)) => {
1657                            // Lazy/LazyLock: keypath to inner value; get = .get() -> &T wrapped in Some, set = None
1658                            tokens.extend(quote! {
1659                                #[inline(always)]
1660                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1661                                    rust_key_paths::Kp::new(
1662                                        |root: &#name| Some(root.#field_ident.get()),
1663                                        |_root: &mut #name| None,
1664                                    )
1665                                }
1666                            });
1667                        }
1668                        (WrapperKind::PhantomData, Some(_inner_ty)) => {
1669                            tokens.extend(quote! {
1670                                #[inline(always)]
1671                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1672                                    rust_key_paths::Kp::new(
1673                                        |root: &#name| Some(&root.#field_ident),
1674                                        |root: &mut #name| Some(&mut root.#field_ident),
1675                                    )
1676                                }
1677                            });
1678                        }
1679                        (WrapperKind::Range, Some(_inner_ty)) => {
1680                            tokens.extend(quote! {
1681                                #[inline(always)]
1682                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1683                                    rust_key_paths::Kp::new(
1684                                        |root: &#name| Some(&root.#field_ident),
1685                                        |root: &mut #name| Some(&mut root.#field_ident),
1686                                    )
1687                                }
1688                            });
1689                        }
1690                        (WrapperKind::OptionCell, Some(_inner_ty)) => {
1691                            tokens.extend(quote! {
1692                                #[inline(always)]
1693                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1694                                    rust_key_paths::Kp::new(
1695                                        |root: &#name| Some(&root.#field_ident),
1696                                        |root: &mut #name| Some(&mut root.#field_ident),
1697                                    )
1698                                }
1699                            });
1700                        }
1701                        (WrapperKind::OptionRefCell, Some(_inner_ty)) => {
1702                            tokens.extend(quote! {
1703                                #[inline(always)]
1704                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1705                                    rust_key_paths::Kp::new(
1706                                        |root: &#name| Some(&root.#field_ident),
1707                                        |root: &mut #name| Some(&mut root.#field_ident),
1708                                    )
1709                                }
1710                            });
1711                        }
1712                        (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
1713                            tokens.extend(quote! {
1714                                #[inline(always)]
1715                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1716                                    rust_key_paths::Kp::new(
1717                                        |root: &#name| root.#field_ident.as_ref().and_then(|c| c.get()),
1718                                        |_root: &mut #name| None,
1719                                    )
1720                                }
1721                            });
1722                        }
1723                        (WrapperKind::OptionLazy, Some(inner_ty)) => {
1724                            tokens.extend(quote! {
1725                                #[inline(always)]
1726                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1727                                    rust_key_paths::Kp::new(
1728                                        |root: &#name| root.#field_ident.as_ref().map(|c| c.get()),
1729                                        |_root: &mut #name| None,
1730                                    )
1731                                }
1732                            });
1733                        }
1734                        (WrapperKind::OptionPhantomData, Some(_inner_ty)) => {
1735                            tokens.extend(quote! {
1736                                #[inline(always)]
1737                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1738                                    rust_key_paths::Kp::new(
1739                                        |root: &#name| Some(&root.#field_ident),
1740                                        |root: &mut #name| Some(&mut root.#field_ident),
1741                                    )
1742                                }
1743                            });
1744                        }
1745                        (WrapperKind::OptionRange, Some(_inner_ty)) => {
1746                            tokens.extend(quote! {
1747                                #[inline(always)]
1748                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1749                                    rust_key_paths::Kp::new(
1750                                        |root: &#name| Some(&root.#field_ident),
1751                                        |root: &mut #name| Some(&mut root.#field_ident),
1752                                    )
1753                                }
1754                            });
1755                        }
1756                        (WrapperKind::Reference, Some(_inner_ty)) => {
1757                            // For reference types (&T, &str, &[T]): read-only, setter returns None
1758                            tokens.extend(quote! {
1759                                #[inline(always)]
1760                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1761                                    rust_key_paths::Kp::new(
1762                                        |root: &#name| Some(&root.#field_ident),
1763                                        |_root: &mut #name| None, // references: read-only
1764                                    )
1765                                }
1766                            });
1767                        }
1768                        (WrapperKind::None, None) => {
1769                            // For basic types, direct access
1770                            tokens.extend(quote! {
1771                                #[inline(always)]
1772                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1773                                    rust_key_paths::Kp::new(
1774                                        |root: &#name| Some(&root.#field_ident),
1775                                        |root: &mut #name| Some(&mut root.#field_ident),
1776                                    )
1777                                }
1778                            });
1779                        }
1780                        _ => {
1781                            // For unknown/complex nested types, return keypath to field itself
1782                            tokens.extend(quote! {
1783                                #[inline(always)]
1784                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1785                            rust_key_paths::Kp::new(
1786                                |root: &#name| Some(&root.#field_ident),
1787                                |root: &mut #name| Some(&mut root.#field_ident),
1788                            )
1789                        }
1790                            });
1791                        }
1792                    }
1793                }
1794                
1795                tokens
1796            }
1797            Fields::Unnamed(unnamed) => {
1798                let mut tokens = proc_macro2::TokenStream::new();
1799
1800                // Generate identity methods for the tuple struct
1801                tokens.extend(quote! {
1802                    /// Returns a generic identity keypath for this type
1803                    #[inline(always)]
1804                    pub fn identity_typed<Root, MutRoot>() -> rust_key_paths::Kp<
1805                        #name,
1806                        #name,
1807                        Root,
1808                        Root,
1809                        MutRoot,
1810                        MutRoot,
1811                        fn(Root) -> Option<Root>,
1812                        fn(MutRoot) -> Option<MutRoot>,
1813                    >
1814                    where
1815                        Root: std::borrow::Borrow<#name>,
1816                        MutRoot: std::borrow::BorrowMut<#name>,
1817                    {
1818                        rust_key_paths::Kp::new(
1819                            |r: Root| Some(r),
1820                            |r: MutRoot| Some(r)
1821                        )
1822                    }
1823
1824                    /// Returns a simple identity keypath for this type
1825                    #[inline(always)]
1826                    pub fn identity() -> rust_key_paths::KpType<'static, #name, #name> {
1827                        rust_key_paths::Kp::new(
1828                            |r: &#name| Some(r),
1829                            |r: &mut #name| Some(r)
1830                        )
1831                    }
1832                });
1833
1834                for (idx, field) in unnamed.unnamed.iter().enumerate() {
1835                    let idx_lit = syn::Index::from(idx);
1836                    let ty = &field.ty;
1837                    // Centralized keypath method names for tuple fields – change here to adjust for all types
1838                    let kp_fn = format_ident!("f{}", idx);
1839                    let kp_at_fn = format_ident!("f{}_at", idx);
1840
1841                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
1842
1843                    match (kind, inner_ty.clone()) {
1844                        (WrapperKind::Option, Some(inner_ty)) => {
1845                            tokens.extend(quote! {
1846                                #[inline(always)]
1847                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1848                                    rust_key_paths::Kp::new(
1849                                        |root: &#name| root.#idx_lit.as_ref(),
1850                                        |root: &mut #name| root.#idx_lit.as_mut(),
1851                                    )
1852                                }
1853                            });
1854                        }
1855                        (WrapperKind::OptionBox, Some(inner_ty)) => {
1856                            tokens.extend(quote! {
1857                                #[inline(always)]
1858                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1859                                    rust_key_paths::Kp::new(
1860                                        |root: &#name| root.#idx_lit.as_deref(),
1861                                        |root: &mut #name| root.#idx_lit.as_deref_mut(),
1862                                    )
1863                                }
1864                            });
1865                        }
1866                        (WrapperKind::OptionRc, Some(inner_ty)) => {
1867                            tokens.extend(quote! {
1868                                #[inline(always)]
1869                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1870                                    rust_key_paths::Kp::new(
1871                                        |root: &#name| root.#idx_lit.as_deref(),
1872                                        |root: &mut #name| root.#idx_lit.as_mut().and_then(std::rc::Rc::get_mut),
1873                                    )
1874                                }
1875                            });
1876                        }
1877                        (WrapperKind::OptionArc, Some(inner_ty)) => {
1878                            tokens.extend(quote! {
1879                                #[inline(always)]
1880                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1881                                    rust_key_paths::Kp::new(
1882                                        |root: &#name| root.#idx_lit.as_deref(),
1883                                        |root: &mut #name| root.#idx_lit.as_mut().and_then(std::sync::Arc::get_mut),
1884                                    )
1885                                }
1886                            });
1887                        }
1888                        (WrapperKind::OptionVecDeque, Some(_inner_ty))
1889                        | (WrapperKind::OptionLinkedList, Some(_inner_ty))
1890                        | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
1891                        | (WrapperKind::OptionHashSet, Some(_inner_ty))
1892                        | (WrapperKind::OptionBTreeSet, Some(_inner_ty))
1893                        | (WrapperKind::OptionResult, Some(_inner_ty))
1894                        | (WrapperKind::OptionBTreeMap, Some(_inner_ty)) => {
1895                            tokens.extend(quote! {
1896                                #[inline(always)]
1897                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1898                                    rust_key_paths::Kp::new(
1899                                        |root: &#name| Some(&root.#idx_lit),
1900                                        |root: &mut #name| Some(&mut root.#idx_lit),
1901                                    )
1902                                }
1903                            });
1904                        }
1905                        (WrapperKind::Vec, Some(inner_ty)) => {
1906                            tokens.extend(quote! {
1907                                #[inline(always)]
1908                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1909                                    rust_key_paths::Kp::new(
1910                                        |root: &#name| Some(&root.#idx_lit),
1911                                        |root: &mut #name| Some(&mut root.#idx_lit),
1912                                    )
1913                                }
1914                                #[inline(always)]
1915                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1916                                    rust_key_paths::Kp::new(
1917                                        Box::new(move |root: &#name| root.#idx_lit.get(index)),
1918                                        Box::new(move |root: &mut #name| root.#idx_lit.get_mut(index)),
1919                                    )
1920                                }
1921                            });
1922                        }
1923                        (WrapperKind::HashMap, Some(inner_ty)) => {
1924                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
1925                                tokens.extend(quote! {
1926                                    #[inline(always)]
1927                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1928                                        rust_key_paths::Kp::new(
1929                                            |root: &#name| Some(&root.#idx_lit),
1930                                            |root: &mut #name| Some(&mut root.#idx_lit),
1931                                        )
1932                                    }
1933                                    #[inline(always)]
1934                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1935                                    where
1936                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
1937                                    {
1938                                        let key2 = key.clone();
1939                                        rust_key_paths::Kp::new(
1940                                            Box::new(move |root: &#name| root.#idx_lit.get(&key)),
1941                                            Box::new(move |root: &mut #name| root.#idx_lit.get_mut(&key2)),
1942                                        )
1943                                    }
1944                                });
1945                            } else {
1946                                tokens.extend(quote! {
1947                                    #[inline(always)]
1948                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1949                                        rust_key_paths::Kp::new(
1950                                            |root: &#name| Some(&root.#idx_lit),
1951                                            |root: &mut #name| Some(&mut root.#idx_lit),
1952                                        )
1953                                    }
1954                                });
1955                            }
1956                        }
1957                        (WrapperKind::BTreeMap, Some(inner_ty)) | (WrapperKind::BTreeMapOption, Some(inner_ty)) => {
1958                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
1959                                tokens.extend(quote! {
1960                                    #[inline(always)]
1961                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1962                                        rust_key_paths::Kp::new(
1963                                            |root: &#name| Some(&root.#idx_lit),
1964                                            |root: &mut #name| Some(&mut root.#idx_lit),
1965                                        )
1966                                    }
1967                                    #[inline(always)]
1968                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1969                                    where
1970                                        #key_ty: Clone + Ord + 'static,
1971                                    {
1972                                        let key2 = key.clone();
1973                                        rust_key_paths::Kp::new(
1974                                            Box::new(move |root: &#name| root.#idx_lit.get(&key)),
1975                                            Box::new(move |root: &mut #name| root.#idx_lit.get_mut(&key2)),
1976                                        )
1977                                    }
1978                                });
1979                            } else {
1980                                tokens.extend(quote! {
1981                                    #[inline(always)]
1982                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1983                                        rust_key_paths::Kp::new(
1984                                            |root: &#name| Some(&root.#idx_lit),
1985                                            |root: &mut #name| Some(&mut root.#idx_lit),
1986                                        )
1987                                    }
1988                                });
1989                            }
1990                        }
1991                        (WrapperKind::Box, Some(inner_ty)) => {
1992                            // Box: deref to inner (returns &T / &mut T)
1993                            tokens.extend(quote! {
1994                                #[inline(always)]
1995                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1996                                    rust_key_paths::Kp::new(
1997                                        |root: &#name| Some(&*root.#idx_lit),
1998                                        |root: &mut #name| Some(&mut *root.#idx_lit),
1999                                    )
2000                                }
2001                            });
2002                        }
2003                        (WrapperKind::BoxOption, Some(inner_ty)) => {
2004                            tokens.extend(quote! {
2005                                #[inline(always)]
2006                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2007                                    rust_key_paths::Kp::new(
2008                                        |root: &#name| (&*root.#idx_lit).as_ref(),
2009                                        |root: &mut #name| (&mut *root.#idx_lit).as_mut(),
2010                                    )
2011                                }
2012                            });
2013                        }
2014                        (WrapperKind::RcOption, Some(inner_ty)) => {
2015                            tokens.extend(quote! {
2016                                #[inline(always)]
2017                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2018                                    rust_key_paths::Kp::new(
2019                                        |root: &#name| (&*root.#idx_lit).as_ref(),
2020                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#idx_lit).and_then(std::option::Option::as_mut),
2021                                    )
2022                                }
2023                            });
2024                        }
2025                        (WrapperKind::ArcOption, Some(inner_ty)) => {
2026                            tokens.extend(quote! {
2027                                #[inline(always)]
2028                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2029                                    rust_key_paths::Kp::new(
2030                                        |root: &#name| (&*root.#idx_lit).as_ref(),
2031                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#idx_lit).and_then(std::option::Option::as_mut),
2032                                    )
2033                                }
2034                            });
2035                        }
2036                        (WrapperKind::Pin, Some(inner_ty)) => {
2037                            let kp_inner_fn = format_ident!("{}_inner", kp_fn);
2038                            tokens.extend(quote! {
2039                                #[inline(always)]
2040                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2041                                    rust_key_paths::Kp::new(
2042                                        |root: &#name| Some(&root.#idx_lit),
2043                                        |root: &mut #name| Some(&mut root.#idx_lit),
2044                                    )
2045                                }
2046                                #[inline(always)]
2047                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2048                                where #inner_ty: std::marker::Unpin
2049                                {
2050                                    rust_key_paths::Kp::new(
2051                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#idx_lit).get_ref()),
2052                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#idx_lit).get_mut()),
2053                                    )
2054                                }
2055                            });
2056                        }
2057                        (WrapperKind::PinBox, Some(inner_ty)) => {
2058                            let kp_inner_fn = format_ident!("{}_inner", kp_fn);
2059                            tokens.extend(quote! {
2060                                #[inline(always)]
2061                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2062                                    rust_key_paths::Kp::new(
2063                                        |root: &#name| Some(&root.#idx_lit),
2064                                        |root: &mut #name| Some(&mut root.#idx_lit),
2065                                    )
2066                                }
2067                                #[inline(always)]
2068                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2069                                where #inner_ty: std::marker::Unpin
2070                                {
2071                                    rust_key_paths::Kp::new(
2072                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#idx_lit).get_ref()),
2073                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#idx_lit).get_mut()),
2074                                    )
2075                                }
2076                            });
2077                        }
2078                        (WrapperKind::Rc, Some(inner_ty)) => {
2079                            tokens.extend(quote! {
2080                                #[inline(always)]
2081                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2082                                    rust_key_paths::Kp::new(
2083                                        |root: &#name| Some(root.#idx_lit.as_ref()),
2084                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#idx_lit),
2085                                    )
2086                                }
2087                            });
2088                        }
2089                        (WrapperKind::Arc, Some(inner_ty)) => {
2090                            tokens.extend(quote! {
2091                                #[inline(always)]
2092                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2093                                    rust_key_paths::Kp::new(
2094                                        |root: &#name| Some(root.#idx_lit.as_ref()),
2095                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#idx_lit),
2096                                    )
2097                                }
2098                            });
2099                        }
2100                        
2101                        (WrapperKind::Cow, Some(inner_ty)) => {
2102                            tokens.extend(quote! {
2103                                #[inline(always)]
2104                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2105                                    rust_key_paths::Kp::new(
2106                                        |root: &#name| Some(root.#idx_lit.as_ref()),
2107                                        |root: &mut #name| Some(root.#idx_lit.to_mut()),
2108                                    )
2109                                }
2110                            });
2111                        }
2112                        
2113                        (WrapperKind::OptionCow, Some(inner_ty)) => {
2114                            tokens.extend(quote! {
2115                                #[inline(always)]
2116                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2117                                    rust_key_paths::Kp::new(
2118                                        |root: &#name| root.#idx_lit.as_ref().map(|c| c.as_ref()),
2119                                        |root: &mut #name| root.#idx_lit.as_mut().map(|c| c.to_mut()),
2120                                    )
2121                                }
2122                            });
2123                        }
2124                        (WrapperKind::OptionTagged, Some(inner_ty)) => {
2125                            tokens.extend(quote! {
2126                                #[inline(always)]
2127                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2128                                    rust_key_paths::Kp::new(
2129                                        |root: &#name| root.#idx_lit.as_ref().map(|t| std::ops::Deref::deref(t)),
2130                                        |root: &mut #name| root.#idx_lit.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
2131                                    )
2132                                }
2133                            });
2134                        }
2135                        (WrapperKind::OptionReference, Some(inner_ty)) => {
2136                            tokens.extend(quote! {
2137                                #[inline(always)]
2138                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2139                                    rust_key_paths::Kp::new(
2140                                        |root: &#name| root.#idx_lit.as_ref(),
2141                                        |_root: &mut #name| None,
2142                                    )
2143                                }
2144                            });
2145                        }
2146                        (WrapperKind::HashSet, Some(inner_ty)) | (WrapperKind::HashSetOption, Some(inner_ty)) => {
2147                            let kp_at_fn = format_ident!("f{}_at", idx);
2148
2149                            tokens.extend(quote! {
2150                                #[inline(always)]
2151                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2152                                    rust_key_paths::Kp::new(
2153                                        |root: &#name| Some(&root.#idx_lit),
2154                                        |root: &mut #name| Some(&mut root.#idx_lit),
2155                                    )
2156                                }
2157
2158                                /// _at: check if element exists and get reference.
2159                                /// HashSet does not allow mutable element access (would break hash invariant).
2160                                #[inline(always)]
2161                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
2162                                where
2163                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
2164                                {
2165                                    rust_key_paths::Kp::new(
2166                                        Box::new(move |root: &#name| root.#idx_lit.get(&key)),
2167                                        Box::new(move |_root: &mut #name| None),
2168                                    )
2169                                }
2170                            });
2171                        }
2172                        (WrapperKind::BTreeSet, Some(inner_ty)) | (WrapperKind::BTreeSetOption, Some(inner_ty)) => {
2173                            let kp_at_fn = format_ident!("f{}_at", idx);
2174
2175                            tokens.extend(quote! {
2176                                #[inline(always)]
2177                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2178                                    rust_key_paths::Kp::new(
2179                                        |root: &#name| Some(&root.#idx_lit),
2180                                        |root: &mut #name| Some(&mut root.#idx_lit),
2181                                    )
2182                                }
2183
2184                                /// _at: check if element exists and get reference.
2185                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
2186                                #[inline(always)]
2187                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
2188                                where
2189                                    #inner_ty: Clone + Ord + 'static,
2190                                {
2191                                    rust_key_paths::Kp::new(
2192                                        Box::new(move |root: &#name| root.#idx_lit.get(&key)),
2193                                        Box::new(move |_root: &mut #name| None),
2194                                    )
2195                                }
2196                            });
2197                        }
2198                        (WrapperKind::VecDeque, Some(inner_ty)) | (WrapperKind::VecDequeOption, Some(inner_ty)) => {
2199                            tokens.extend(quote! {
2200                                #[inline(always)]
2201                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2202                                    rust_key_paths::Kp::new(
2203                                        |root: &#name| Some(&root.#idx_lit),
2204                                        |root: &mut #name| Some(&mut root.#idx_lit),
2205                                    )
2206                                }
2207                                #[inline(always)]
2208                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
2209                                    rust_key_paths::Kp::new(
2210                                        Box::new(move |root: &#name| root.#idx_lit.get(index)),
2211                                        Box::new(move |root: &mut #name| root.#idx_lit.get_mut(index)),
2212                                    )
2213                                }
2214                            });
2215                        }
2216                        (WrapperKind::LinkedList, Some(_inner_ty)) | (WrapperKind::LinkedListOption, Some(_inner_ty)) => {
2217                            tokens.extend(quote! {
2218                                #[inline(always)]
2219                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2220                                    rust_key_paths::Kp::new(
2221                                        |root: &#name| Some(&root.#idx_lit),
2222                                        |root: &mut #name| Some(&mut root.#idx_lit),
2223                                    )
2224                                }
2225                            });
2226                        }
2227                        (WrapperKind::BinaryHeap, Some(_inner_ty)) | (WrapperKind::BinaryHeapOption, Some(_inner_ty)) => {
2228                            tokens.extend(quote! {
2229                                #[inline(always)]
2230                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2231                                    rust_key_paths::Kp::new(
2232                                        |root: &#name| Some(&root.#idx_lit),
2233                                        |root: &mut #name| Some(&mut root.#idx_lit),
2234                                    )
2235                                }
2236                            });
2237                        }
2238                        (WrapperKind::Result, Some(inner_ty)) => {
2239                            tokens.extend(quote! {
2240                                #[inline(always)]
2241                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2242                                    rust_key_paths::Kp::new(
2243                                        |root: &#name| root.#idx_lit.as_ref().ok(),
2244                                        |root: &mut #name| root.#idx_lit.as_mut().ok(),
2245                                    )
2246                                }
2247                            });
2248                        }
2249                        (WrapperKind::Mutex, Some(_inner_ty))
2250                        | (WrapperKind::StdMutex, Some(_inner_ty)) => {
2251                            tokens.extend(quote! {
2252                                #[inline(always)]
2253                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2254                                    rust_key_paths::Kp::new(
2255                                        |root: &#name| Some(&root.#idx_lit),
2256                                        |root: &mut #name| Some(&mut root.#idx_lit),
2257                                    )
2258                                }
2259                            });
2260                        }
2261                        (WrapperKind::RwLock, Some(_inner_ty))
2262                        | (WrapperKind::StdRwLock, Some(_inner_ty)) => {
2263                            tokens.extend(quote! {
2264                                #[inline(always)]
2265                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2266                                    rust_key_paths::Kp::new(
2267                                        |root: &#name| Some(&root.#idx_lit),
2268                                        |root: &mut #name| Some(&mut root.#idx_lit),
2269                                    )
2270                                }
2271                            });
2272                        }
2273                        (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
2274                            let kp_async_fn = format_ident!("f{}_kp", idx);
2275                            tokens.extend(quote! {
2276                                #[inline(always)]
2277                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2278                                    rust_key_paths::Kp::new(
2279                                        |root: &#name| Some(&root.#idx_lit),
2280                                        |root: &mut #name| Some(&mut root.#idx_lit),
2281                                    )
2282                                }
2283                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #ty, #inner_ty> {
2284                                    rust_key_paths::async_lock::AsyncLockKp::new(
2285                                        rust_key_paths::Kp::new(
2286                                            |root: &#name| Some(&root.#idx_lit),
2287                                            |root: &mut #name| Some(&mut root.#idx_lit),
2288                                        ),
2289                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
2290                                        rust_key_paths::Kp::new(
2291                                            |v: &#inner_ty| Some(v),
2292                                            |v: &mut #inner_ty| Some(v),
2293                                        ),
2294                                    )
2295                                }
2296                            });
2297                        }
2298                        (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
2299                            let kp_async_fn = format_ident!("f{}_kp", idx);
2300                            tokens.extend(quote! {
2301                                #[inline(always)]
2302                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2303                                    rust_key_paths::Kp::new(
2304                                        |root: &#name| Some(&root.#idx_lit),
2305                                        |root: &mut #name| Some(&mut root.#idx_lit),
2306                                    )
2307                                }
2308                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #ty, #inner_ty> {
2309                                    rust_key_paths::async_lock::AsyncLockKp::new(
2310                                        rust_key_paths::Kp::new(
2311                                            |root: &#name| Some(&root.#idx_lit),
2312                                            |root: &mut #name| Some(&mut root.#idx_lit),
2313                                        ),
2314                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
2315                                        rust_key_paths::Kp::new(
2316                                            |v: &#inner_ty| Some(v),
2317                                            |v: &mut #inner_ty| Some(v),
2318                                        ),
2319                                    )
2320                                }
2321                            });
2322                        }
2323                        (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
2324                            let kp_async_fn = format_ident!("f{}_kp", idx);
2325                            tokens.extend(quote! {
2326                                #[inline(always)]
2327                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2328                                    rust_key_paths::Kp::new(
2329                                        |root: &#name| Some(&root.#idx_lit),
2330                                        |root: &mut #name| Some(&mut root.#idx_lit),
2331                                    )
2332                                }
2333                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
2334                                    rust_key_paths::async_lock::AsyncLockKp::new(
2335                                        rust_key_paths::Kp::new(
2336                                            |root: &#name| root.#idx_lit.as_ref(),
2337                                            |root: &mut #name| root.#idx_lit.as_mut(),
2338                                        ),
2339                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
2340                                        rust_key_paths::Kp::new(
2341                                            |v: &#inner_ty| Some(v),
2342                                            |v: &mut #inner_ty| Some(v),
2343                                        ),
2344                                    )
2345                                }
2346                            });
2347                        }
2348                        (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
2349                            let kp_async_fn = format_ident!("f{}_kp", idx);
2350                            tokens.extend(quote! {
2351                                #[inline(always)]
2352                                    pub fn #kp_async_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2353                                    rust_key_paths::Kp::new(
2354                                        |root: &#name| Some(&root.#idx_lit),
2355                                        |root: &mut #name| Some(&mut root.#idx_lit),
2356                                    )
2357                                }
2358                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
2359                                    rust_key_paths::async_lock::AsyncLockKp::new(
2360                                        rust_key_paths::Kp::new(
2361                                            |root: &#name| root.#idx_lit.as_ref(),
2362                                            |root: &mut #name| root.#idx_lit.as_mut(),
2363                                        ),
2364                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
2365                                        rust_key_paths::Kp::new(
2366                                            |v: &#inner_ty| Some(v),
2367                                            |v: &mut #inner_ty| Some(v),
2368                                        ),
2369                                    )
2370                                }
2371                            });
2372                        }
2373                        (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
2374                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2375                            tokens.extend(quote! {
2376                                #[inline(always)]
2377                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2378                                    rust_key_paths::Kp::new(
2379                                        |root: &#name| Some(&root.#idx_lit),
2380                                        |root: &mut #name| Some(&mut root.#idx_lit),
2381                                    )
2382                                }
2383                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::Mutex<#inner_ty>>> {
2384                                    rust_key_paths::Kp::new(
2385                                        |root: &#name| root.#idx_lit.as_ref(),
2386                                        |root: &mut #name| root.#idx_lit.as_mut(),
2387                                    )
2388                                }
2389                            });
2390                        }
2391                        (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
2392                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2393                            tokens.extend(quote! {
2394                                #[inline(always)]
2395                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2396                                    rust_key_paths::Kp::new(
2397                                        |root: &#name| Some(&root.#idx_lit),
2398                                        |root: &mut #name| Some(&mut root.#idx_lit),
2399                                    )
2400                                }
2401                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>> {
2402                                    rust_key_paths::Kp::new(
2403                                        |root: &#name| root.#idx_lit.as_ref(),
2404                                        |root: &mut #name| root.#idx_lit.as_mut(),
2405                                    )
2406                                }
2407                            });
2408                        }
2409                        (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
2410                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2411                            tokens.extend(quote! {
2412                                #[inline(always)]
2413                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2414                                    rust_key_paths::Kp::new(
2415                                        |root: &#name| Some(&root.#idx_lit),
2416                                        |root: &mut #name| Some(&mut root.#idx_lit),
2417                                    )
2418                                }
2419                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::RwLock<#inner_ty>>> {
2420                                    rust_key_paths::Kp::new(
2421                                        |root: &#name| root.#idx_lit.as_ref(),
2422                                        |root: &mut #name| root.#idx_lit.as_mut(),
2423                                    )
2424                                }
2425                            });
2426                        }
2427                        (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
2428                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2429                            tokens.extend(quote! {
2430                                #[inline(always)]
2431                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2432                                    rust_key_paths::Kp::new(
2433                                        |root: &#name| Some(&root.#idx_lit),
2434                                        |root: &mut #name| Some(&mut root.#idx_lit),
2435                                    )
2436                                }
2437                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>> {
2438                                    rust_key_paths::Kp::new(
2439                                        |root: &#name| root.#idx_lit.as_ref(),
2440                                        |root: &mut #name| root.#idx_lit.as_mut(),
2441                                    )
2442                                }
2443                            });
2444                        }
2445                        (WrapperKind::OptionStdMutex, Some(inner_ty))
2446                        | (WrapperKind::OptionMutex, Some(inner_ty)) => {
2447                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2448                            tokens.extend(quote! {
2449                                #[inline(always)]
2450                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2451                                    rust_key_paths::Kp::new(
2452                                        |root: &#name| Some(&root.#idx_lit),
2453                                        |root: &mut #name| Some(&mut root.#idx_lit),
2454                                    )
2455                                }
2456                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Mutex<#inner_ty>> {
2457                                    rust_key_paths::Kp::new(
2458                                        |root: &#name| root.#idx_lit.as_ref(),
2459                                        |root: &mut #name| root.#idx_lit.as_mut(),
2460                                    )
2461                                }
2462                            });
2463                        }
2464                        (WrapperKind::OptionStdRwLock, Some(inner_ty))
2465                        | (WrapperKind::OptionRwLock, Some(inner_ty)) => {
2466                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2467                            tokens.extend(quote! {
2468                                #[inline(always)]
2469                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2470                                    rust_key_paths::Kp::new(
2471                                        |root: &#name| Some(&root.#idx_lit),
2472                                        |root: &mut #name| Some(&mut root.#idx_lit),
2473                                    )
2474                                }
2475                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::RwLock<#inner_ty>> {
2476                                    rust_key_paths::Kp::new(
2477                                        |root: &#name| root.#idx_lit.as_ref(),
2478                                        |root: &mut #name| root.#idx_lit.as_mut(),
2479                                    )
2480                                }
2481                            });
2482                        }
2483                        (WrapperKind::Weak, Some(_inner_ty)) => {
2484                            tokens.extend(quote! {
2485                                #[inline(always)]
2486                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2487                                    rust_key_paths::Kp::new(
2488                                        |root: &#name| Some(&root.#idx_lit),
2489                                        |_root: &mut #name| None,
2490                                    )
2491                                }
2492                            });
2493                        }
2494                        (WrapperKind::Atomic, None | Some(_)) => {
2495                            tokens.extend(quote! {
2496                                #[inline(always)]
2497                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2498                                    rust_key_paths::Kp::new(
2499                                        |root: &#name| Some(&root.#idx_lit),
2500                                        |root: &mut #name| Some(&mut root.#idx_lit),
2501                                    )
2502                                }
2503                            });
2504                        }
2505                        (WrapperKind::OptionAtomic, Some(inner_ty)) => {
2506                            tokens.extend(quote! {
2507                                #[inline(always)]
2508                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2509                                    rust_key_paths::Kp::new(
2510                                        |root: &#name| root.#idx_lit.as_ref(),
2511                                        |root: &mut #name| root.#idx_lit.as_mut(),
2512                                    )
2513                                }
2514                            });
2515                        }
2516                        (WrapperKind::String, None) => {
2517                            tokens.extend(quote! {
2518                                #[inline(always)]
2519                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2520                                    rust_key_paths::Kp::new(
2521                                        |root: &#name| Some(&root.#idx_lit),
2522                                        |root: &mut #name| Some(&mut root.#idx_lit),
2523                                    )
2524                                }
2525                            });
2526                        }
2527                        (WrapperKind::OptionString, None) => {
2528                            tokens.extend(quote! {
2529                                #[inline(always)]
2530                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, std::string::String> {
2531                                    rust_key_paths::Kp::new(
2532                                        |root: &#name| root.#idx_lit.as_ref(),
2533                                        |root: &mut #name| root.#idx_lit.as_mut(),
2534                                    )
2535                                }
2536                            });
2537                        }
2538                        (WrapperKind::OnceCell, Some(inner_ty)) => {
2539                            tokens.extend(quote! {
2540                                #[inline(always)]
2541                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2542                                    rust_key_paths::Kp::new(
2543                                        |root: &#name| root.#idx_lit.get(),
2544                                        |_root: &mut #name| None,
2545                                    )
2546                                }
2547                            });
2548                        }
2549                        (WrapperKind::Lazy, Some(inner_ty)) => {
2550                            tokens.extend(quote! {
2551                                #[inline(always)]
2552                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2553                                    rust_key_paths::Kp::new(
2554                                        |root: &#name| Some(root.#idx_lit.get()),
2555                                        |_root: &mut #name| None,
2556                                    )
2557                                }
2558                            });
2559                        }
2560                        (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
2561                            tokens.extend(quote! {
2562                                #[inline(always)]
2563                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2564                                    rust_key_paths::Kp::new(
2565                                        |root: &#name| root.#idx_lit.as_ref().and_then(|c| c.get()),
2566                                        |_root: &mut #name| None,
2567                                    )
2568                                }
2569                            });
2570                        }
2571                        (WrapperKind::OptionLazy, Some(inner_ty)) => {
2572                            tokens.extend(quote! {
2573                                #[inline(always)]
2574                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2575                                    rust_key_paths::Kp::new(
2576                                        |root: &#name| root.#idx_lit.as_ref().map(|c| c.get()),
2577                                        |_root: &mut #name| None,
2578                                    )
2579                                }
2580                            });
2581                        }
2582                        (WrapperKind::Cell, Some(_inner_ty)) | (WrapperKind::RefCell, Some(_inner_ty))
2583                        | (WrapperKind::PhantomData, Some(_inner_ty)) | (WrapperKind::Range, Some(_inner_ty))
2584                        | (WrapperKind::OptionCell, Some(_inner_ty)) | (WrapperKind::OptionRefCell, Some(_inner_ty))
2585                        | (WrapperKind::OptionPhantomData, Some(_inner_ty)) | (WrapperKind::OptionRange, Some(_inner_ty)) => {
2586                            tokens.extend(quote! {
2587                                #[inline(always)]
2588                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2589                                    rust_key_paths::Kp::new(
2590                                        |root: &#name| Some(&root.#idx_lit),
2591                                        |root: &mut #name| Some(&mut root.#idx_lit),
2592                                    )
2593                                }
2594                            });
2595                        }
2596                        (WrapperKind::Reference, Some(_inner_ty)) => {
2597                            tokens.extend(quote! {
2598                                #[inline(always)]
2599                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2600                                    rust_key_paths::Kp::new(
2601                                        |root: &#name| Some(&root.#idx_lit),
2602                                        |_root: &mut #name| None,
2603                                    )
2604                                }
2605                            });
2606                        }
2607                        (WrapperKind::None, None) => {
2608                            tokens.extend(quote! {
2609                                #[inline(always)]
2610                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2611                                    rust_key_paths::Kp::new(
2612                                        |root: &#name| Some(&root.#idx_lit),
2613                                        |root: &mut #name| Some(&mut root.#idx_lit),
2614                                    )
2615                                }
2616                            });
2617                        }
2618                        _ => {
2619                            tokens.extend(quote! {
2620                                #[inline(always)]
2621                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2622                                    rust_key_paths::Kp::new(
2623                                        |root: &#name| Some(&root.#idx_lit),
2624                                        |root: &mut #name| Some(&mut root.#idx_lit),
2625                                    )
2626                                }
2627                            });
2628                        }
2629                    }
2630                }
2631
2632                tokens
2633            }
2634            Fields::Unit => {
2635                return syn::Error::new(input_span, "Kp derive does not support unit structs")
2636                .to_compile_error()
2637                .into();
2638            }
2639        },
2640        Data::Enum(data_enum) => {
2641            let mut tokens = proc_macro2::TokenStream::new();
2642
2643            // Generate identity methods for the enum
2644            tokens.extend(quote! {
2645                /// Returns a generic identity keypath for this type
2646                #[inline(always)]
2647                pub fn identity_typed<Root, MutRoot>() -> rust_key_paths::Kp<
2648                    #name,
2649                    #name,
2650                    Root,
2651                    Root,
2652                    MutRoot,
2653                    MutRoot,
2654                    fn(Root) -> Option<Root>,
2655                    fn(MutRoot) -> Option<MutRoot>,
2656                >
2657                where
2658                    Root: std::borrow::Borrow<#name>,
2659                    MutRoot: std::borrow::BorrowMut<#name>,
2660                {
2661                    rust_key_paths::Kp::new(
2662                        |r: Root| Some(r),
2663                        |r: MutRoot| Some(r)
2664                    )
2665                }
2666
2667                /// Returns a simple identity keypath for this type
2668                #[inline(always)]
2669                pub fn identity() -> rust_key_paths::KpType<'static, #name, #name> {
2670                    rust_key_paths::Kp::new(
2671                        |r: &#name| Some(r),
2672                        |r: &mut #name| Some(r)
2673                    )
2674                }
2675            });
2676
2677            for variant in data_enum.variants.iter() {
2678                let v_ident = &variant.ident;
2679                let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
2680
2681                match &variant.fields {
2682                    Fields::Unit => {
2683                        // Unit variant - return keypath that checks if enum matches variant
2684                        tokens.extend(quote! {
2685                            #[inline(always)]
2686                            pub fn #snake() -> rust_key_paths::KpType<'static, #name, ()> {
2687                                rust_key_paths::Kp::new(
2688                                    |root: &#name| match root {
2689                                        #name::#v_ident => {
2690                                            static UNIT: () = ();
2691                                            Some(&UNIT)
2692                                        },
2693                                        _ => None,
2694                                    },
2695                                    |_root: &mut #name| None, // Can't mutate unit variant
2696                                )
2697                            }
2698                        });
2699                    }
2700                    Fields::Unnamed(unnamed) => {
2701                        if unnamed.unnamed.len() == 1 {
2702                            // Single-field tuple variant
2703                            let field_ty = &unnamed.unnamed[0].ty;
2704                            let (kind, inner_ty) = extract_wrapper_inner_type(field_ty);
2705
2706                            match (kind, inner_ty.clone()) {
2707                                (WrapperKind::Option, Some(inner_ty)) => {
2708                                    tokens.extend(quote! {
2709                                        #[inline(always)]
2710                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2711                                            rust_key_paths::Kp::new(
2712                                                |root: &#name| match root {
2713                                                    #name::#v_ident(inner) => inner.as_ref(),
2714                                                    _ => None,
2715                                                },
2716                                                |root: &mut #name| match root {
2717                                                    #name::#v_ident(inner) => inner.as_mut(),
2718                                                    _ => None,
2719                                                },
2720                                            )
2721                                        }
2722                                    });
2723                                }
2724                                (WrapperKind::OptionVecDeque, Some(_inner_ty))
2725                                | (WrapperKind::OptionLinkedList, Some(_inner_ty))
2726                                | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
2727                                | (WrapperKind::OptionHashSet, Some(_inner_ty))
2728                                | (WrapperKind::OptionBTreeSet, Some(_inner_ty))
2729                                | (WrapperKind::OptionResult, Some(_inner_ty))
2730                                | (WrapperKind::OptionBTreeMap, Some(_inner_ty)) => {
2731                                    tokens.extend(quote! {
2732                                        #[inline(always)]
2733                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2734                                            rust_key_paths::Kp::new(
2735                                                |root: &#name| match root {
2736                                                    #name::#v_ident(inner) => Some(inner),
2737                                                    _ => None,
2738                                                },
2739                                                |root: &mut #name| match root {
2740                                                    #name::#v_ident(inner) => Some(inner),
2741                                                    _ => None,
2742                                                },
2743                                            )
2744                                        }
2745                                    });
2746                                }
2747                                (WrapperKind::Vec, Some(inner_ty)) => {
2748                                    tokens.extend(quote! {
2749                                        #[inline(always)]
2750                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2751                                            rust_key_paths::Kp::new(
2752                                                |root: &#name| match root {
2753                                                    #name::#v_ident(inner) => inner.first(),
2754                                                    _ => None,
2755                                                },
2756                                                |root: &mut #name| match root {
2757                                                    #name::#v_ident(inner) => inner.first_mut(),
2758                                                    _ => None,
2759                                                },
2760                                            )
2761                                        }
2762                                    });
2763                                }
2764                                (WrapperKind::Box, Some(inner_ty)) => {
2765                                    // Box in enum: deref to inner (&T / &mut T)
2766                                    tokens.extend(quote! {
2767                                        #[inline(always)]
2768                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2769                                            rust_key_paths::Kp::new(
2770                                                |root: &#name| match root {
2771                                                    #name::#v_ident(inner) => Some(&**inner),
2772                                                    _ => None,
2773                                                },
2774                                                |root: &mut #name| match root {
2775                                                    #name::#v_ident(inner) => Some(&mut **inner),
2776                                                    _ => None,
2777                                                },
2778                                            )
2779                                        }
2780                                    });
2781                                }
2782                                (WrapperKind::Pin, Some(inner_ty)) => {
2783                                    let snake_inner = format_ident!("{}_inner", snake);
2784                                    tokens.extend(quote! {
2785                                        #[inline(always)]
2786                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2787                                            rust_key_paths::Kp::new(
2788                                                |root: &#name| match root {
2789                                                    #name::#v_ident(inner) => Some(inner),
2790                                                    _ => None,
2791                                                },
2792                                                |root: &mut #name| match root {
2793                                                    #name::#v_ident(inner) => Some(inner),
2794                                                    _ => None,
2795                                                },
2796                                            )
2797                                        }
2798                                        #[inline(always)]
2799                                        pub fn #snake_inner() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2800                                        where #inner_ty: std::marker::Unpin
2801                                        {
2802                                            rust_key_paths::Kp::new(
2803                                                |root: &#name| match root {
2804                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_ref(inner).get_ref()),
2805                                                    _ => None,
2806                                                },
2807                                                |root: &mut #name| match root {
2808                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_mut(inner).get_mut()),
2809                                                    _ => None,
2810                                                },
2811                                            )
2812                                        }
2813                                    });
2814                                }
2815                                (WrapperKind::PinBox, Some(inner_ty)) => {
2816                                    let snake_inner = format_ident!("{}_inner", snake);
2817                                    tokens.extend(quote! {
2818                                        #[inline(always)]
2819                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2820                                            rust_key_paths::Kp::new(
2821                                                |root: &#name| match root {
2822                                                    #name::#v_ident(inner) => Some(inner),
2823                                                    _ => None,
2824                                                },
2825                                                |root: &mut #name| match root {
2826                                                    #name::#v_ident(inner) => Some(inner),
2827                                                    _ => None,
2828                                                },
2829                                            )
2830                                        }
2831                                        #[inline(always)]
2832                                        pub fn #snake_inner() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2833                                        where #inner_ty: std::marker::Unpin
2834                                        {
2835                                            rust_key_paths::Kp::new(
2836                                                |root: &#name| match root {
2837                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_ref(inner).get_ref()),
2838                                                    _ => None,
2839                                                },
2840                                                |root: &mut #name| match root {
2841                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_mut(inner).get_mut()),
2842                                                    _ => None,
2843                                                },
2844                                            )
2845                                        }
2846                                    });
2847                                }
2848                                (WrapperKind::Rc, Some(inner_ty)) => {
2849                                    tokens.extend(quote! {
2850                                        #[inline(always)]
2851                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2852                                            rust_key_paths::Kp::new(
2853                                                |root: &#name| match root {
2854                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
2855                                                    _ => None,
2856                                                },
2857                                                |root: &mut #name| match root {
2858                                                    #name::#v_ident(inner) => std::rc::Rc::get_mut(inner),
2859                                                    _ => None,
2860                                                },
2861                                            )
2862                                        }
2863                                    });
2864                                }
2865                                (WrapperKind::Arc, Some(inner_ty)) => {
2866                                    tokens.extend(quote! {
2867                                        #[inline(always)]
2868                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2869                                            rust_key_paths::Kp::new(
2870                                                |root: &#name| match root {
2871                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
2872                                                    _ => None,
2873                                                },
2874                                                |root: &mut #name| match root {
2875                                                    #name::#v_ident(inner) => std::sync::Arc::get_mut(inner),
2876                                                    _ => None,
2877                                                },
2878                                            )
2879                                        }
2880                                    });
2881                                }
2882                                (WrapperKind::StdArcRwLock, Some(inner_ty)) => {
2883                                    let snake_lock = format_ident!("{}_lock", snake);
2884                                    tokens.extend(quote! {
2885                                        #[inline(always)]
2886                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2887                                            rust_key_paths::Kp::new(
2888                                                |root: &#name| match root {
2889                                                    #name::#v_ident(inner) => Some(inner),
2890                                                    _ => None,
2891                                                },
2892                                                |root: &mut #name| match root {
2893                                                    #name::#v_ident(inner) => Some(inner),
2894                                                    _ => None,
2895                                                },
2896                                            )
2897                                        }
2898                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, #field_ty, #inner_ty> {
2899                                            rust_key_paths::lock::LockKp::new(
2900                                                rust_key_paths::Kp::new(
2901                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2902                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2903                                                ),
2904                                                rust_key_paths::lock::ArcRwLockAccess::new(),
2905                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2906                                            )
2907                                        }
2908                                    });
2909                                }
2910                                (WrapperKind::StdArcMutex, Some(inner_ty)) => {
2911                                    let snake_lock = format_ident!("{}_lock", snake);
2912                                    tokens.extend(quote! {
2913                                        #[inline(always)]
2914                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2915                                            rust_key_paths::Kp::new(
2916                                                |root: &#name| match root {
2917                                                    #name::#v_ident(inner) => Some(inner),
2918                                                    _ => None,
2919                                                },
2920                                                |root: &mut #name| match root {
2921                                                    #name::#v_ident(inner) => Some(inner),
2922                                                    _ => None,
2923                                                },
2924                                            )
2925                                        }
2926                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexFor<#name, #field_ty, #inner_ty> {
2927                                            rust_key_paths::lock::LockKp::new(
2928                                                rust_key_paths::Kp::new(
2929                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2930                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2931                                                ),
2932                                                rust_key_paths::lock::ArcMutexAccess::new(),
2933                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2934                                            )
2935                                        }
2936                                    });
2937                                }
2938                                (WrapperKind::ArcRwLock, Some(inner_ty)) => {
2939                                    let snake_lock = format_ident!("{}_lock", snake);
2940                                    tokens.extend(quote! {
2941                                        #[inline(always)]
2942                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2943                                            rust_key_paths::Kp::new(
2944                                                |root: &#name| match root {
2945                                                    #name::#v_ident(inner) => Some(inner),
2946                                                    _ => None,
2947                                                },
2948                                                |root: &mut #name| match root {
2949                                                    #name::#v_ident(inner) => Some(inner),
2950                                                    _ => None,
2951                                                },
2952                                            )
2953                                        }
2954                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, #field_ty, #inner_ty> {
2955                                            rust_key_paths::lock::LockKp::new(
2956                                                rust_key_paths::Kp::new(
2957                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2958                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2959                                                ),
2960                                                rust_key_paths::lock::ParkingLotRwLockAccess::new(),
2961                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2962                                            )
2963                                        }
2964                                    });
2965                                }
2966                                (WrapperKind::ArcMutex, Some(inner_ty)) => {
2967                                    let snake_lock = format_ident!("{}_lock", snake);
2968                                    tokens.extend(quote! {
2969                                        #[inline(always)]
2970                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2971                                            rust_key_paths::Kp::new(
2972                                                |root: &#name| match root {
2973                                                    #name::#v_ident(inner) => Some(inner),
2974                                                    _ => None,
2975                                                },
2976                                                |root: &mut #name| match root {
2977                                                    #name::#v_ident(inner) => Some(inner),
2978                                                    _ => None,
2979                                                },
2980                                            )
2981                                        }
2982                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, #field_ty, #inner_ty> {
2983                                            rust_key_paths::lock::LockKp::new(
2984                                                rust_key_paths::Kp::new(
2985                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2986                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2987                                                ),
2988                                                rust_key_paths::lock::ParkingLotMutexAccess::new(),
2989                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2990                                            )
2991                                        }
2992                                    });
2993                                }
2994                                (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
2995                                    let snake_async = format_ident!("{}_kp", snake);
2996                                    tokens.extend(quote! {
2997                                        #[inline(always)]
2998                                        pub fn #snake_async() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2999                                            rust_key_paths::Kp::new(
3000                                                |root: &#name| match root {
3001                                                    #name::#v_ident(inner) => Some(inner),
3002                                                    _ => None,
3003                                                },
3004                                                |root: &mut #name| match root {
3005                                                    #name::#v_ident(inner) => Some(inner),
3006                                                    _ => None,
3007                                                },
3008                                            )
3009                                        }
3010                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #field_ty, #inner_ty> {
3011                                            rust_key_paths::async_lock::AsyncLockKp::new(
3012                                                rust_key_paths::Kp::new(
3013                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
3014                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
3015                                                ),
3016                                                rust_key_paths::async_lock::TokioMutexAccess::new(),
3017                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3018                                            )
3019                                        }
3020                                    });
3021                                }
3022                                (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
3023                                    let snake_async = format_ident!("{}_kp", snake);
3024                                    tokens.extend(quote! {
3025                                        #[inline(always)]
3026                                        pub fn #snake_async() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3027                                            rust_key_paths::Kp::new(
3028                                                |root: &#name| match root {
3029                                                    #name::#v_ident(inner) => Some(inner),
3030                                                    _ => None,
3031                                                },
3032                                                |root: &mut #name| match root {
3033                                                    #name::#v_ident(inner) => Some(inner),
3034                                                    _ => None,
3035                                                },
3036                                            )
3037                                        }
3038                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #field_ty, #inner_ty> {
3039                                            rust_key_paths::async_lock::AsyncLockKp::new(
3040                                                rust_key_paths::Kp::new(
3041                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
3042                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
3043                                                ),
3044                                                rust_key_paths::async_lock::TokioRwLockAccess::new(),
3045                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3046                                            )
3047                                        }
3048                                    });
3049                                }
3050                                (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
3051                                    let snake_async = format_ident!("{}_kp", snake);
3052                                    tokens.extend(quote! {
3053                                        #[inline(always)]
3054                                        pub fn #snake_async() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3055                                            rust_key_paths::Kp::new(
3056                                                |root: &#name| match root {
3057                                                    #name::#v_ident(inner) => Some(inner),
3058                                                    _ => None,
3059                                                },
3060                                                |root: &mut #name| match root {
3061                                                    #name::#v_ident(inner) => Some(inner),
3062                                                    _ => None,
3063                                                },
3064                                            )
3065                                        }
3066                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
3067                                            rust_key_paths::async_lock::AsyncLockKp::new(
3068                                                rust_key_paths::Kp::new(
3069                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3070                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3071                                                ),
3072                                                rust_key_paths::async_lock::TokioMutexAccess::new(),
3073                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3074                                            )
3075                                        }
3076                                    });
3077                                }
3078                                (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
3079                                    let snake_async = format_ident!("{}_kp", snake);
3080                                    tokens.extend(quote! {
3081                                        #[inline(always)]
3082                                        pub fn #snake_async() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3083                                            rust_key_paths::Kp::new(
3084                                                |root: &#name| match root {
3085                                                    #name::#v_ident(inner) => Some(inner),
3086                                                    _ => None,
3087                                                },
3088                                                |root: &mut #name| match root {
3089                                                    #name::#v_ident(inner) => Some(inner),
3090                                                    _ => None,
3091                                                },
3092                                            )
3093                                        }
3094                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
3095                                            rust_key_paths::async_lock::AsyncLockKp::new(
3096                                                rust_key_paths::Kp::new(
3097                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3098                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3099                                                ),
3100                                                rust_key_paths::async_lock::TokioRwLockAccess::new(),
3101                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3102                                            )
3103                                        }
3104                                    });
3105                                }
3106                                (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
3107                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3108                                    let snake_lock = format_ident!("{}_lock", snake);
3109                                    tokens.extend(quote! {
3110                                        #[inline(always)]
3111                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3112                                            rust_key_paths::Kp::new(
3113                                                |root: &#name| match root {
3114                                                    #name::#v_ident(inner) => Some(inner),
3115                                                    _ => None,
3116                                                },
3117                                                |root: &mut #name| match root {
3118                                                    #name::#v_ident(inner) => Some(inner),
3119                                                    _ => None,
3120                                                },
3121                                            )
3122                                        }
3123                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::Mutex<#inner_ty>>> {
3124                                            rust_key_paths::Kp::new(
3125                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3126                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3127                                            )
3128                                        }
3129                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexFor<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, #inner_ty> {
3130                                            rust_key_paths::lock::LockKp::new(
3131                                                rust_key_paths::Kp::new(
3132                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3133                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3134                                                ),
3135                                                rust_key_paths::lock::ArcMutexAccess::new(),
3136                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3137                                            )
3138                                        }
3139                                    });
3140                                }
3141                                (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
3142                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3143                                    let snake_lock = format_ident!("{}_lock", snake);
3144                                    tokens.extend(quote! {
3145                                        #[inline(always)]
3146                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3147                                            rust_key_paths::Kp::new(
3148                                                |root: &#name| match root {
3149                                                    #name::#v_ident(inner) => Some(inner),
3150                                                    _ => None,
3151                                                },
3152                                                |root: &mut #name| match root {
3153                                                    #name::#v_ident(inner) => Some(inner),
3154                                                    _ => None,
3155                                                },
3156                                            )
3157                                        }
3158                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>> {
3159                                            rust_key_paths::Kp::new(
3160                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3161                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3162                                            )
3163                                        }
3164                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, #inner_ty> {
3165                                            rust_key_paths::lock::LockKp::new(
3166                                                rust_key_paths::Kp::new(
3167                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3168                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3169                                                ),
3170                                                rust_key_paths::lock::ParkingLotMutexAccess::new(),
3171                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3172                                            )
3173                                        }
3174                                    });
3175                                }
3176                                (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
3177                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3178                                    let snake_lock = format_ident!("{}_lock", snake);
3179                                    tokens.extend(quote! {
3180                                        #[inline(always)]
3181                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3182                                            rust_key_paths::Kp::new(
3183                                                |root: &#name| match root {
3184                                                    #name::#v_ident(inner) => Some(inner),
3185                                                    _ => None,
3186                                                },
3187                                                |root: &mut #name| match root {
3188                                                    #name::#v_ident(inner) => Some(inner),
3189                                                    _ => None,
3190                                                },
3191                                            )
3192                                        }
3193                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::RwLock<#inner_ty>>> {
3194                                            rust_key_paths::Kp::new(
3195                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3196                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3197                                            )
3198                                        }
3199                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, #inner_ty> {
3200                                            rust_key_paths::lock::LockKp::new(
3201                                                rust_key_paths::Kp::new(
3202                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3203                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3204                                                ),
3205                                                rust_key_paths::lock::ArcRwLockAccess::new(),
3206                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3207                                            )
3208                                        }
3209                                    });
3210                                }
3211                                (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
3212                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3213                                    let snake_lock = format_ident!("{}_lock", snake);
3214                                    tokens.extend(quote! {
3215                                        #[inline(always)]
3216                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3217                                            rust_key_paths::Kp::new(
3218                                                |root: &#name| match root {
3219                                                    #name::#v_ident(inner) => Some(inner),
3220                                                    _ => None,
3221                                                },
3222                                                |root: &mut #name| match root {
3223                                                    #name::#v_ident(inner) => Some(inner),
3224                                                    _ => None,
3225                                                },
3226                                            )
3227                                        }
3228                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>> {
3229                                            rust_key_paths::Kp::new(
3230                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3231                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3232                                            )
3233                                        }
3234                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, #inner_ty> {
3235                                            rust_key_paths::lock::LockKp::new(
3236                                                rust_key_paths::Kp::new(
3237                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3238                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3239                                                ),
3240                                                rust_key_paths::lock::ParkingLotRwLockAccess::new(),
3241                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3242                                            )
3243                                        }
3244                                    });
3245                                }
3246                                (WrapperKind::StdMutex, Some(_inner_ty))
3247                                | (WrapperKind::Mutex, Some(_inner_ty))
3248                                | (WrapperKind::StdRwLock, Some(_inner_ty))
3249                                | (WrapperKind::RwLock, Some(_inner_ty)) => {
3250                                    tokens.extend(quote! {
3251                                        #[inline(always)]
3252                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3253                                            rust_key_paths::Kp::new(
3254                                                |root: &#name| match root {
3255                                                    #name::#v_ident(inner) => Some(inner),
3256                                                    _ => None,
3257                                                },
3258                                                |root: &mut #name| match root {
3259                                                    #name::#v_ident(inner) => Some(inner),
3260                                                    _ => None,
3261                                                },
3262                                            )
3263                                        }
3264                                    });
3265                                }
3266                                (WrapperKind::Tagged, Some(inner_ty)) => {
3267                                    tokens.extend(quote! {
3268                                        #[inline(always)]
3269                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3270                                            rust_key_paths::Kp::new(
3271                                                |root: &#name| match root {
3272                                                    #name::#v_ident(inner) => Some(std::ops::Deref::deref(inner)),
3273                                                    _ => None,
3274                                                },
3275                                                |root: &mut #name| match root {
3276                                                    #name::#v_ident(inner) => Some(std::ops::DerefMut::deref_mut(inner)),
3277                                                    _ => None,
3278                                                },
3279                                            )
3280                                        }
3281                                    });
3282                                }
3283                                (WrapperKind::Atomic, None | Some(_)) => {
3284                                    tokens.extend(quote! {
3285                                        #[inline(always)]
3286                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3287                                            rust_key_paths::Kp::new(
3288                                                |root: &#name| match root {
3289                                                    #name::#v_ident(inner) => Some(inner),
3290                                                    _ => None,
3291                                                },
3292                                                |root: &mut #name| match root {
3293                                                    #name::#v_ident(inner) => Some(inner),
3294                                                    _ => None,
3295                                                },
3296                                            )
3297                                        }
3298                                    });
3299                                }
3300                                (WrapperKind::OptionAtomic, Some(inner_ty)) => {
3301                                    tokens.extend(quote! {
3302                                        #[inline(always)]
3303                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3304                                            rust_key_paths::Kp::new(
3305                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3306                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3307                                            )
3308                                        }
3309                                    });
3310                                }
3311                                (WrapperKind::Reference, Some(_inner_ty)) => {
3312                                    tokens.extend(quote! {
3313                                        #[inline(always)]
3314                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3315                                            rust_key_paths::Kp::new(
3316                                                |root: &#name| match root {
3317                                                    #name::#v_ident(inner) => Some(inner),
3318                                                    _ => None,
3319                                                },
3320                                                |_root: &mut #name| None,
3321                                            )
3322                                        }
3323                                    });
3324                                }
3325                                (WrapperKind::Weak, Some(_inner_ty)) => {
3326                                    tokens.extend(quote! {
3327                                        #[inline(always)]
3328                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3329                                            rust_key_paths::Kp::new(
3330                                                |root: &#name| match root {
3331                                                    #name::#v_ident(inner) => Some(inner),
3332                                                    _ => None,
3333                                                },
3334                                                |_root: &mut #name| None,
3335                                            )
3336                                        }
3337                                    });
3338                                }
3339                                (WrapperKind::Cow, Some(inner_ty)) => {
3340                                    tokens.extend(quote! {
3341                                        #[inline(always)]
3342                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3343                                            rust_key_paths::Kp::new(
3344                                                |root: &#name| match root {
3345                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
3346                                                    _ => None,
3347                                                },
3348                                                |root: &mut #name| match root {
3349                                                    #name::#v_ident(inner) => Some(inner.to_mut()),
3350                                                    _ => None,
3351                                                },
3352                                            )
3353                                        }
3354                                    });
3355                                }
3356                                (WrapperKind::OptionBox, Some(inner_ty)) => {
3357                                    // Option<Box<T>>: keypath to T via as_deref() / as_deref_mut()
3358                                    tokens.extend(quote! {
3359                                        #[inline(always)]
3360                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3361                                            rust_key_paths::Kp::new(
3362                                                |root: &#name| match root {
3363                                                    #name::#v_ident(inner) => inner.as_deref(),
3364                                                    _ => None,
3365                                                },
3366                                                |root: &mut #name| match root {
3367                                                    #name::#v_ident(inner) => inner.as_deref_mut(),
3368                                                    _ => None,
3369                                                },
3370                                            )
3371                                        }
3372                                    });
3373                                }
3374                                (WrapperKind::BoxOption, Some(inner_ty)) => {
3375                                    // Box<Option<T>>: keypath to T; inner is &Box<Option<T>>, deref then Option::as_ref/as_mut
3376                                    tokens.extend(quote! {
3377                                        #[inline(always)]
3378                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3379                                            rust_key_paths::Kp::new(
3380                                                |root: &#name| match root {
3381                                                    #name::#v_ident(inner) => (&*inner).as_ref(),
3382                                                    _ => None,
3383                                                },
3384                                                |root: &mut #name| match root {
3385                                                    #name::#v_ident(inner) => (&mut *inner).as_mut(),
3386                                                    _ => None,
3387                                                },
3388                                            )
3389                                        }
3390                                    });
3391                                }
3392                                (WrapperKind::RcOption, Some(inner_ty)) => {
3393                                    // Rc<Option<T>>: keypath to T; get = (&*inner).as_ref(), set = Rc::get_mut then as_mut
3394                                    tokens.extend(quote! {
3395                                        #[inline(always)]
3396                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3397                                            rust_key_paths::Kp::new(
3398                                                |root: &#name| match root {
3399                                                    #name::#v_ident(inner) => (&*inner).as_ref(),
3400                                                    _ => None,
3401                                                },
3402                                                |root: &mut #name| match root {
3403                                                    #name::#v_ident(inner) => std::rc::Rc::get_mut(inner).and_then(std::option::Option::as_mut),
3404                                                    _ => None,
3405                                                },
3406                                            )
3407                                        }
3408                                    });
3409                                }
3410                                (WrapperKind::ArcOption, Some(inner_ty)) => {
3411                                    // Arc<Option<T>>: keypath to T; get = (&*inner).as_ref(), set = Arc::get_mut then as_mut
3412                                    tokens.extend(quote! {
3413                                        #[inline(always)]
3414                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3415                                            rust_key_paths::Kp::new(
3416                                                |root: &#name| match root {
3417                                                    #name::#v_ident(inner) => (&*inner).as_ref(),
3418                                                    _ => None,
3419                                                },
3420                                                |root: &mut #name| match root {
3421                                                    #name::#v_ident(inner) => std::sync::Arc::get_mut(inner).and_then(std::option::Option::as_mut),
3422                                                    _ => None,
3423                                                },
3424                                            )
3425                                        }
3426                                    });
3427                                }
3428                                (WrapperKind::OptionRc, Some(inner_ty)) => {
3429                                    tokens.extend(quote! {
3430                                        #[inline(always)]
3431                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3432                                            rust_key_paths::Kp::new(
3433                                                |root: &#name| match root {
3434                                                    #name::#v_ident(inner) => inner.as_deref(),
3435                                                    _ => None,
3436                                                },
3437                                                |root: &mut #name| match root {
3438                                                    #name::#v_ident(inner) => inner.as_mut().and_then(std::rc::Rc::get_mut),
3439                                                    _ => None,
3440                                                },
3441                                            )
3442                                        }
3443                                    });
3444                                }
3445                                (WrapperKind::OptionArc, Some(inner_ty)) => {
3446                                    tokens.extend(quote! {
3447                                        #[inline(always)]
3448                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3449                                            rust_key_paths::Kp::new(
3450                                                |root: &#name| match root {
3451                                                    #name::#v_ident(inner) => inner.as_deref(),
3452                                                    _ => None,
3453                                                },
3454                                                |root: &mut #name| match root {
3455                                                    #name::#v_ident(inner) => inner.as_mut().and_then(std::sync::Arc::get_mut),
3456                                                    _ => None,
3457                                                },
3458                                            )
3459                                        }
3460                                    });
3461                                }
3462                                (WrapperKind::OptionCow, Some(inner_ty)) => {
3463                                    tokens.extend(quote! {
3464                                        #[inline(always)]
3465                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3466                                            rust_key_paths::Kp::new(
3467                                                |root: &#name| match root {
3468                                                    #name::#v_ident(inner) => inner.as_ref().map(|c| c.as_ref()),
3469                                                    _ => None,
3470                                                },
3471                                                |root: &mut #name| match root {
3472                                                    #name::#v_ident(inner) => inner.as_mut().map(|c| c.to_mut()),
3473                                                    _ => None,
3474                                                },
3475                                            )
3476                                        }
3477                                    });
3478                                }
3479                                (WrapperKind::OptionTagged, Some(inner_ty)) => {
3480                                    tokens.extend(quote! {
3481                                        #[inline(always)]
3482                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3483                                            rust_key_paths::Kp::new(
3484                                                |root: &#name| match root {
3485                                                    #name::#v_ident(inner) => inner.as_ref().map(|t| std::ops::Deref::deref(t)),
3486                                                    _ => None,
3487                                                },
3488                                                |root: &mut #name| match root {
3489                                                    #name::#v_ident(inner) => inner.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
3490                                                    _ => None,
3491                                                },
3492                                            )
3493                                        }
3494                                    });
3495                                }
3496                                (WrapperKind::OptionReference, Some(inner_ty)) => {
3497                                    tokens.extend(quote! {
3498                                        #[inline(always)]
3499                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3500                                            rust_key_paths::Kp::new(
3501                                                |root: &#name| match root {
3502                                                    #name::#v_ident(inner) => inner.as_ref(),
3503                                                    _ => None,
3504                                                },
3505                                                |_root: &mut #name| None,
3506                                            )
3507                                        }
3508                                    });
3509                                }
3510                                (WrapperKind::String, None) => {
3511                                    tokens.extend(quote! {
3512                                        #[inline(always)]
3513                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3514                                            rust_key_paths::Kp::new(
3515                                                |root: &#name| match root {
3516                                                    #name::#v_ident(inner) => Some(inner),
3517                                                    _ => None,
3518                                                },
3519                                                |root: &mut #name| match root {
3520                                                    #name::#v_ident(inner) => Some(inner),
3521                                                    _ => None,
3522                                                },
3523                                            )
3524                                        }
3525                                    });
3526                                }
3527                                (WrapperKind::OptionString, None) => {
3528                                    tokens.extend(quote! {
3529                                        #[inline(always)]
3530                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, std::string::String> {
3531                                            rust_key_paths::Kp::new(
3532                                                |root: &#name| match root {
3533                                                    #name::#v_ident(inner) => inner.as_ref(),
3534                                                    _ => None,
3535                                                },
3536                                                |root: &mut #name| match root {
3537                                                    #name::#v_ident(inner) => inner.as_mut(),
3538                                                    _ => None,
3539                                                },
3540                                            )
3541                                        }
3542                                    });
3543                                }
3544                                (WrapperKind::OnceCell, Some(inner_ty)) => {
3545                                    tokens.extend(quote! {
3546                                        #[inline(always)]
3547                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3548                                            rust_key_paths::Kp::new(
3549                                                |root: &#name| match root {
3550                                                    #name::#v_ident(inner) => inner.get(),
3551                                                    _ => None,
3552                                                },
3553                                                |_root: &mut #name| None,
3554                                            )
3555                                        }
3556                                    });
3557                                }
3558                                (WrapperKind::Lazy, Some(inner_ty)) => {
3559                                    tokens.extend(quote! {
3560                                        #[inline(always)]
3561                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3562                                            rust_key_paths::Kp::new(
3563                                                |root: &#name| match root {
3564                                                    #name::#v_ident(inner) => Some(inner.get()),
3565                                                    _ => None,
3566                                                },
3567                                                |_root: &mut #name| None,
3568                                            )
3569                                        }
3570                                    });
3571                                }
3572                                (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
3573                                    tokens.extend(quote! {
3574                                        #[inline(always)]
3575                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3576                                            rust_key_paths::Kp::new(
3577                                                |root: &#name| match root {
3578                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|c| c.get()),
3579                                                    _ => None,
3580                                                },
3581                                                |_root: &mut #name| None,
3582                                            )
3583                                        }
3584                                    });
3585                                }
3586                                (WrapperKind::OptionLazy, Some(inner_ty)) => {
3587                                    tokens.extend(quote! {
3588                                        #[inline(always)]
3589                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3590                                            rust_key_paths::Kp::new(
3591                                                |root: &#name| match root {
3592                                                    #name::#v_ident(inner) => inner.as_ref().map(|c| c.get()),
3593                                                    _ => None,
3594                                                },
3595                                                |_root: &mut #name| None,
3596                                            )
3597                                        }
3598                                    });
3599                                }
3600                                (WrapperKind::Cell, Some(_inner_ty)) | (WrapperKind::RefCell, Some(_inner_ty))
3601                                | (WrapperKind::PhantomData, Some(_inner_ty)) | (WrapperKind::Range, Some(_inner_ty))
3602                                | (WrapperKind::OptionCell, Some(_inner_ty)) | (WrapperKind::OptionRefCell, Some(_inner_ty))
3603                                | (WrapperKind::OptionPhantomData, Some(_inner_ty)) | (WrapperKind::OptionRange, Some(_inner_ty)) => {
3604                                    tokens.extend(quote! {
3605                                        #[inline(always)]
3606                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3607                                            rust_key_paths::Kp::new(
3608                                                |root: &#name| match root {
3609                                                    #name::#v_ident(inner) => Some(inner),
3610                                                    _ => None,
3611                                                },
3612                                                |root: &mut #name| match root {
3613                                                    #name::#v_ident(inner) => Some(inner),
3614                                                    _ => None,
3615                                                },
3616                                            )
3617                                        }
3618                                    });
3619                                }
3620                                (WrapperKind::None, None) => {
3621                                    // Basic type
3622                                    tokens.extend(quote! {
3623                                        #[inline(always)]
3624                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3625                                            rust_key_paths::Kp::new(
3626                                                |root: &#name| match root {
3627                                                    #name::#v_ident(inner) => Some(inner),
3628                                                    _ => None,
3629                                                },
3630                                                |root: &mut #name| match root {
3631                                                    #name::#v_ident(inner) => Some(inner),
3632                                                    _ => None,
3633                                                },
3634                                            )
3635                                        }
3636                                    });
3637                                }
3638                                _ => {
3639                                    // Other wrapper types - return keypath to field
3640                                    tokens.extend(quote! {
3641                                        #[inline(always)]
3642                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3643                                            rust_key_paths::Kp::new(
3644                                                |root: &#name| match root {
3645                                                    #name::#v_ident(inner) => Some(inner),
3646                                                    _ => None,
3647                                                },
3648                                                |root: &mut #name| match root {
3649                                                    #name::#v_ident(inner) => Some(inner),
3650                                                    _ => None,
3651                                                },
3652                                            )
3653                                        }
3654                                    });
3655                                }
3656                            }
3657                        } else {
3658                            // Multi-field tuple variant - return keypath to variant itself
3659                            tokens.extend(quote! {
3660                                #[inline(always)]
3661                                pub fn #snake() -> rust_key_paths::KpType<'static, #name, #name> {
3662                                    rust_key_paths::Kp::new(
3663                                        |root: &#name| match root {
3664                                            #name::#v_ident(..) => Some(root),
3665                                            _ => None,
3666                                        },
3667                                        |root: &mut #name| match root {
3668                                            #name::#v_ident(..) => Some(root),
3669                                            _ => None,
3670                                        },
3671                                    )
3672                                }
3673                            });
3674                        }
3675                    }
3676                    Fields::Named(_) => {
3677                        // Named field variant - return keypath to variant itself
3678                        tokens.extend(quote! {
3679                            pub fn #snake() -> rust_key_paths::KpType<'static, #name, #name> {
3680                                rust_key_paths::Kp::new(
3681                                    |root: &#name| match root {
3682                                        #name::#v_ident { .. } => Some(root),
3683                                        _ => None,
3684                                    },
3685                                    |root: &mut #name| match root {
3686                                        #name::#v_ident { .. } => Some(root),
3687                                        _ => None,
3688                                    },
3689                                )
3690                            }
3691                        });
3692                    }
3693                }
3694            }
3695
3696            tokens
3697        }
3698        Data::Union(_) => {
3699            return syn::Error::new(input_span, "Kp derive does not support unions")
3700            .to_compile_error()
3701            .into();
3702        }
3703    };
3704
3705    let expanded = quote! {
3706        impl #name {
3707            #methods
3708        }
3709    };
3710
3711    TokenStream::from(expanded)
3712}
3713
3714/// Derive macro that generates `partial_kps() -> Vec<PKp<Self>>` returning all field/variant keypaths.
3715/// **Requires `#[derive(Kp)]`** so the keypath accessor methods exist.
3716///
3717/// For structs: returns keypaths for each field. For enums: returns keypaths for each variant
3718/// (using the same methods Kp generates, e.g. `some_variant()`).
3719///
3720/// # Example
3721/// ```
3722/// use key_paths_derive::{Kp, Pkp};
3723/// use rust_key_paths::PKp;
3724///
3725/// #[derive(Kp, Pkp)]
3726/// struct Person {
3727///     name: String,
3728///     age: i32,
3729/// }
3730///
3731/// let kps = Person::partial_kps();
3732/// assert_eq!(kps.len(), 2);
3733/// ```
3734#[proc_macro_derive(Pkp)]
3735pub fn derive_partial_keypaths(input: TokenStream) -> TokenStream {
3736    let input = parse_macro_input!(input as DeriveInput);
3737    let name = &input.ident;
3738
3739    let kp_calls = match &input.data {
3740        Data::Struct(data_struct) => match &data_struct.fields {
3741            Fields::Named(fields_named) => {
3742                let calls: Vec<_> = fields_named
3743                    .named
3744                    .iter()
3745                    .filter_map(|f| f.ident.as_ref())
3746                    .map(|field_ident| {
3747                        quote! { rust_key_paths::PKp::new(Self::#field_ident()) }
3748                    })
3749                    .collect();
3750                quote! { #(#calls),* }
3751            }
3752            Fields::Unnamed(unnamed) => {
3753                let calls: Vec<_> = (0..unnamed.unnamed.len())
3754                    .map(|idx| {
3755                        let kp_fn = format_ident!("f{}", idx);
3756                        quote! { rust_key_paths::PKp::new(Self::#kp_fn()) }
3757                    })
3758                    .collect();
3759                quote! { #(#calls),* }
3760            }
3761            Fields::Unit => quote! {},
3762        },
3763        Data::Enum(data_enum) => {
3764            let calls: Vec<_> = data_enum
3765                .variants
3766                .iter()
3767                .map(|variant| {
3768                    let v_ident = &variant.ident;
3769                    let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
3770                    quote! { rust_key_paths::PKp::new(Self::#snake()) }
3771                })
3772                .collect();
3773            quote! { #(#calls),* }
3774        }
3775        Data::Union(_) => {
3776            return syn::Error::new(
3777                input.ident.span(),
3778                "Pkp derive does not support unions",
3779            )
3780            .to_compile_error()
3781            .into();
3782        }
3783    };
3784
3785    let expanded = quote! {
3786        impl #name {
3787            /// Returns a vec of all field keypaths as partial keypaths (type-erased).
3788            #[inline(always)]
3789            pub fn partial_kps() -> Vec<rust_key_paths::PKp<#name>> {
3790                vec![#kp_calls]
3791            }
3792        }
3793    };
3794
3795    TokenStream::from(expanded)
3796}
3797
3798/// Derive macro that generates `any_kps() -> Vec<AKp>` returning all field/variant keypaths as any keypaths.
3799/// **Requires `#[derive(Kp)]`** so the keypath accessor methods exist.
3800/// AKp type-erases both Root and Value, enabling heterogeneous collections of keypaths.
3801///
3802/// For structs: returns keypaths for each field. For enums: returns keypaths for each variant
3803/// (using the same methods Kp generates, e.g. `some_variant()`).
3804///
3805/// # Example
3806/// ```
3807/// use key_paths_derive::{Kp, Akp};
3808/// use rust_key_paths::AKp;
3809///
3810/// #[derive(Kp, Akp)]
3811/// struct Person {
3812///     name: String,
3813///     age: i32,
3814/// }
3815///
3816/// let kps = Person::any_kps();
3817/// assert_eq!(kps.len(), 2);
3818/// let person = Person { name: "Alice".into(), age: 30 };
3819/// let name: Option<&String> = kps[0].get(&person as &dyn std::any::Any).and_then(|v| v.downcast_ref());
3820/// assert_eq!(name, Some(&"Alice".to_string()));
3821/// ```
3822#[proc_macro_derive(Akp)]
3823pub fn derive_any_keypaths(input: TokenStream) -> TokenStream {
3824    let input = parse_macro_input!(input as DeriveInput);
3825    let name = &input.ident;
3826
3827    let kp_calls = match &input.data {
3828        Data::Struct(data_struct) => match &data_struct.fields {
3829            Fields::Named(fields_named) => {
3830                let calls: Vec<_> = fields_named
3831                    .named
3832                    .iter()
3833                    .filter_map(|f| f.ident.as_ref())
3834                    .map(|field_ident| {
3835                        quote! { rust_key_paths::AKp::new(Self::#field_ident()) }
3836                    })
3837                    .collect();
3838                quote! { #(#calls),* }
3839            }
3840            Fields::Unnamed(unnamed) => {
3841                let calls: Vec<_> = (0..unnamed.unnamed.len())
3842                    .map(|idx| {
3843                        let kp_fn = format_ident!("f{}", idx);
3844                        quote! { rust_key_paths::AKp::new(Self::#kp_fn()) }
3845                    })
3846                    .collect();
3847                quote! { #(#calls),* }
3848            }
3849            Fields::Unit => quote! {},
3850        },
3851        Data::Enum(data_enum) => {
3852            let calls: Vec<_> = data_enum
3853                .variants
3854                .iter()
3855                .map(|variant| {
3856                    let v_ident = &variant.ident;
3857                    let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
3858                    quote! { rust_key_paths::AKp::new(Self::#snake()) }
3859                })
3860                .collect();
3861            quote! { #(#calls),* }
3862        }
3863        Data::Union(_) => {
3864            return syn::Error::new(
3865                input.ident.span(),
3866                "Akp derive does not support unions",
3867            )
3868            .to_compile_error()
3869            .into();
3870        }
3871    };
3872
3873    let expanded = quote! {
3874        impl #name {
3875            /// Returns a vec of all field keypaths as any keypaths (fully type-erased).
3876            #[inline(always)]
3877            pub fn any_kps() -> Vec<rust_key_paths::AKp> {
3878                vec![#kp_calls]
3879            }
3880        }
3881    };
3882
3883    TokenStream::from(expanded)
3884}