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::Pin, Some(inner_ty)) => {
837                            let kp_inner_fn = format_ident!("{}_inner", field_ident);
838                            tokens.extend(quote! {
839                                #[inline(always)]
840                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
841                                    rust_key_paths::Kp::new(
842                                        |root: &#name| Some(&root.#field_ident),
843                                        |root: &mut #name| Some(&mut root.#field_ident),
844                                    )
845                                }
846                                #[inline(always)]
847                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
848                                where #inner_ty: std::marker::Unpin
849                                {
850                                    rust_key_paths::Kp::new(
851                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#field_ident).get_ref()),
852                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#field_ident).get_mut()),
853                                    )
854                                }
855                            });
856                        }
857                        (WrapperKind::PinBox, Some(inner_ty)) => {
858                            let kp_inner_fn = format_ident!("{}_inner", field_ident);
859                            tokens.extend(quote! {
860                                #[inline(always)]
861                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
862                                    rust_key_paths::Kp::new(
863                                        |root: &#name| Some(&root.#field_ident),
864                                        |root: &mut #name| Some(&mut root.#field_ident),
865                                    )
866                                }
867                                #[inline(always)]
868                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
869                                where #inner_ty: std::marker::Unpin
870                                {
871                                    // Pin::as_ref on Pin<Box<T>> returns Pin<&T> (Box Deref target), so get_ref() already gives &T
872                                    rust_key_paths::Kp::new(
873                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#field_ident).get_ref()),
874                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#field_ident).get_mut()),
875                                    )
876                                }
877                            });
878                        }
879                        (WrapperKind::PinnedField, _) => {
880                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
881                            tokens.extend(quote! {
882                                #[inline(always)]
883                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
884                                    rust_key_paths::Kp::new(
885                                        |root: &#name| Some(&root.#field_ident),
886                                        |root: &mut #name| Some(&mut root.#field_ident),
887                                    )
888                                }
889                                /// Pinned projection for #[pin] field. Requires #[pin_project] on struct.
890                                #[inline(always)]
891                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
892                                    this.project().#field_ident
893                                }
894                            });
895                        }
896                        (WrapperKind::PinnedFuture, _) => {
897                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
898                            let kp_await_fn = format_ident!("{}_await", field_ident);
899                            let kp_pin_future_fn = format_ident!("{}_pin_future_kp", field_ident);
900                            let output_ty = quote! { <#ty as std::future::Future>::Output };
901                            tokens.extend(quote! {
902                                #[inline(always)]
903                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
904                                    rust_key_paths::Kp::new(
905                                        |root: &#name| Some(&root.#field_ident),
906                                        |root: &mut #name| Some(&mut root.#field_ident),
907                                    )
908                                }
909                                /// Pinned projection for #[pin] Future field. Requires #[pin_project] on struct.
910                                #[inline(always)]
911                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
912                                    this.project().#field_ident
913                                }
914                                /// Poll the pinned future. Requires #[pin_project] on struct.
915                                pub async fn #kp_await_fn(this: std::pin::Pin<&mut #name>) -> Option<#output_ty>
916                                where #ty: std::future::Future
917                                {
918                                    use std::future::Future;
919                                    Some(this.project().#field_ident.await)
920                                }
921                                /// Keypath for [rust_key_paths::Kp::then_pin_future]. Composable pin future await.
922                                #[inline(always)]
923                                pub fn #kp_pin_future_fn() -> impl rust_key_paths::pin::PinFutureAwaitLike<#name, #output_ty> {
924                                    rust_key_paths::pin_future_await_kp!(#name, #kp_await_fn -> #output_ty)
925                                }
926                            });
927                        }
928                        (WrapperKind::PinnedBoxFuture, Some(output_ty)) => {
929                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
930                            let kp_await_fn = format_ident!("{}_await", field_ident);
931                            let kp_pin_future_fn = format_ident!("{}_pin_future_kp", field_ident);
932                            tokens.extend(quote! {
933                                #[inline(always)]
934                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
935                                    rust_key_paths::Kp::new(
936                                        |root: &#name| Some(&root.#field_ident),
937                                        |root: &mut #name| Some(&mut root.#field_ident),
938                                    )
939                                }
940                                /// Pinned projection for #[pin] Box<dyn Future> field. Requires #[pin_project] on struct.
941                                #[inline(always)]
942                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
943                                    this.project().#field_ident
944                                }
945                                /// Poll the pinned boxed future. Requires #[pin_project] on struct.
946                                pub async fn #kp_await_fn(this: std::pin::Pin<&mut #name>) -> Option<#output_ty> {
947                                    Some(this.project().#field_ident.await)
948                                }
949                                /// Keypath for [rust_key_paths::Kp::then_pin_future]. Composable pin future await.
950                                #[inline(always)]
951                                pub fn #kp_pin_future_fn() -> impl rust_key_paths::pin::PinFutureAwaitLike<#name, #output_ty> {
952                                    rust_key_paths::pin_future_await_kp!(#name, #kp_await_fn -> #output_ty)
953                                }
954                            });
955                        }
956                        (WrapperKind::Rc, Some(inner_ty)) => {
957                            // For Rc<T>, deref to inner type (returns &T; get_mut when uniquely owned)
958                            tokens.extend(quote! {
959                                #[inline(always)]
960                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
961                                    rust_key_paths::Kp::new(
962                                        |root: &#name| Some(root.#field_ident.as_ref()),
963                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#field_ident),
964                                    )
965                                }
966                            });
967                        }
968                        (WrapperKind::Arc, Some(inner_ty)) => {
969                            // For Arc<T>, deref to inner type (returns &T; get_mut when uniquely owned)
970                            tokens.extend(quote! {
971                                #[inline(always)]
972                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
973                                    rust_key_paths::Kp::new(
974                                        |root: &#name| Some(root.#field_ident.as_ref()),
975                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#field_ident),
976                                    )
977                                }
978                            });
979                        }
980                        (WrapperKind::Cow, Some(inner_ty)) => {
981                            // For Cow<'_, B>, deref to inner type (as_ref/to_mut)
982                            tokens.extend(quote! {
983                                #[inline(always)]
984                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
985                                    rust_key_paths::Kp::new(
986                                        |root: &#name| Some(root.#field_ident.as_ref()),
987                                        |root: &mut #name| Some(root.#field_ident.to_mut()),
988                                    )
989                                }
990                            });
991                        }
992                        
993                        (WrapperKind::OptionCow, Some(inner_ty)) => {
994                            // For Option<Cow<'_, B>>
995                            tokens.extend(quote! {
996                                #[inline(always)]
997                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
998                                    rust_key_paths::Kp::new(
999                                        |root: &#name| root.#field_ident.as_ref().map(|c| c.as_ref()),
1000                                        |root: &mut #name| root.#field_ident.as_mut().map(|c| c.to_mut()),
1001                                    )
1002                                }
1003                            });
1004                        }
1005                        (WrapperKind::OptionTagged, Some(inner_ty)) => {
1006                            // For Option<Tagged<Tag, T>> - Tagged implements Deref/DerefMut
1007                            tokens.extend(quote! {
1008                                #[inline(always)]
1009                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1010                                    rust_key_paths::Kp::new(
1011                                        |root: &#name| root.#field_ident.as_ref().map(|t| std::ops::Deref::deref(t)),
1012                                        |root: &mut #name| root.#field_ident.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
1013                                    )
1014                                }
1015                            });
1016                        }
1017                        (WrapperKind::OptionReference, Some(inner_ty)) => {
1018                            // For Option<&T>, Option<&str>, Option<&[T]> - read-only, setter returns None
1019                            tokens.extend(quote! {
1020                                #[inline(always)]
1021                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1022                                    rust_key_paths::Kp::new(
1023                                        |root: &#name| root.#field_ident.as_ref(),
1024                                        |_root: &mut #name| None,
1025                                    )
1026                                }
1027                            });
1028                        }
1029                        (WrapperKind::HashSet, Some(inner_ty)) | (WrapperKind::HashSetOption, Some(inner_ty)) => {
1030                            let kp_at_fn = format_ident!("{}_at", field_ident);
1031
1032                            tokens.extend(quote! {
1033                                #[inline(always)]
1034                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1035                                    rust_key_paths::Kp::new(
1036                                        |root: &#name| Some(&root.#field_ident),
1037                                        |root: &mut #name| Some(&mut root.#field_ident),
1038                                    )
1039                                }
1040
1041                                /// _at: check if element exists and get reference.
1042                                /// HashSet does not allow mutable element access (would break hash invariant).
1043                                #[inline(always)]
1044                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1045                                where
1046                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
1047                                {
1048                                    rust_key_paths::Kp::new(
1049                                        Box::new(move |root: &#name| root.#field_ident.get(&key)),
1050                                        Box::new(move |_root: &mut #name| None),
1051                                    )
1052                                }
1053                            });
1054                        }
1055                        (WrapperKind::BTreeSet, Some(inner_ty)) | (WrapperKind::BTreeSetOption, Some(inner_ty)) => {
1056                            let kp_at_fn = format_ident!("{}_at", field_ident);
1057
1058                            tokens.extend(quote! {
1059                                #[inline(always)]
1060                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1061                                    rust_key_paths::Kp::new(
1062                                        |root: &#name| Some(&root.#field_ident),
1063                                        |root: &mut #name| Some(&mut root.#field_ident),
1064                                    )
1065                                }
1066
1067                                /// _at: check if element exists and get reference.
1068                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
1069                                #[inline(always)]
1070                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1071                                where
1072                                    #inner_ty: Clone + Ord + 'static,
1073                                {
1074                                    rust_key_paths::Kp::new(
1075                                        Box::new(move |root: &#name| root.#field_ident.get(&key)),
1076                                        Box::new(move |_root: &mut #name| None),
1077                                    )
1078                                }
1079                            });
1080                        }
1081                        (WrapperKind::VecDeque, Some(inner_ty)) | (WrapperKind::VecDequeOption, Some(inner_ty)) => {
1082                            tokens.extend(quote! {
1083                                #[inline(always)]
1084                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1085                                    rust_key_paths::Kp::new(
1086                                        |root: &#name| Some(&root.#field_ident),
1087                                        |root: &mut #name| Some(&mut root.#field_ident),
1088                                    )
1089                                }
1090                                #[inline(always)]
1091                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1092                                    rust_key_paths::Kp::new(
1093                                        Box::new(move |root: &#name| root.#field_ident.get(index)),
1094                                        Box::new(move |root: &mut #name| root.#field_ident.get_mut(index)),
1095                                    )
1096                                }
1097                            });
1098                        }
1099                        (WrapperKind::LinkedList, Some(_inner_ty)) | (WrapperKind::LinkedListOption, Some(_inner_ty)) => {
1100                            tokens.extend(quote! {
1101                                #[inline(always)]
1102                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1103                                    rust_key_paths::Kp::new(
1104                                        |root: &#name| Some(&root.#field_ident),
1105                                        |root: &mut #name| Some(&mut root.#field_ident),
1106                                    )
1107                                }
1108                            });
1109                        }
1110                        (WrapperKind::BinaryHeap, Some(_inner_ty)) | (WrapperKind::BinaryHeapOption, Some(_inner_ty)) => {
1111                            tokens.extend(quote! {
1112                                #[inline(always)]
1113                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1114                                    rust_key_paths::Kp::new(
1115                                        |root: &#name| Some(&root.#field_ident),
1116                                        |root: &mut #name| Some(&mut root.#field_ident),
1117                                    )
1118                                }
1119                            });
1120                        }
1121                        (WrapperKind::Result, Some(inner_ty)) => {
1122                            // For Result<T, E>, access Ok value
1123                            tokens.extend(quote! {
1124                                #[inline(always)]
1125                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1126                                    rust_key_paths::Kp::new(
1127                                        |root: &#name| root.#field_ident.as_ref().ok(),
1128                                        |root: &mut #name| root.#field_ident.as_mut().ok(),
1129                                    )
1130                                }
1131                            });
1132                        }
1133                        (WrapperKind::StdArcMutex, Some(inner_ty)) => {
1134                            // For Arc<std::sync::Mutex<T>>
1135                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
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                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpArcMutexFor<#name, #ty, #inner_ty> {
1145                                    rust_key_paths::lock::LockKp::new(
1146                                        rust_key_paths::Kp::new(
1147                                            |root: &#name| Some(&root.#field_ident),
1148                                            |root: &mut #name| Some(&mut root.#field_ident),
1149                                        ),
1150                                        rust_key_paths::lock::ArcMutexAccess::new(),
1151                                        rust_key_paths::Kp::new(
1152                                            |v: &#inner_ty| Some(v),
1153                                            |v: &mut #inner_ty| Some(v),
1154                                        ),
1155                                    )
1156                                }
1157                            });
1158                        }
1159                        (WrapperKind::StdArcRwLock, Some(inner_ty)) => {
1160                            // For Arc<std::sync::RwLock<T>>
1161                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1162                            tokens.extend(quote! {
1163                                #[inline(always)]
1164                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1165                                    rust_key_paths::Kp::new(
1166                                        |root: &#name| Some(&root.#field_ident),
1167                                        |root: &mut #name| Some(&mut root.#field_ident),
1168                                    )
1169                                }
1170                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, #ty, #inner_ty> {
1171                                    rust_key_paths::lock::LockKp::new(
1172                                        rust_key_paths::Kp::new(
1173                                            |root: &#name| Some(&root.#field_ident),
1174                                            |root: &mut #name| Some(&mut root.#field_ident),
1175                                        ),
1176                                        rust_key_paths::lock::ArcRwLockAccess::new(),
1177                                        rust_key_paths::Kp::new(
1178                                            |v: &#inner_ty| Some(v),
1179                                            |v: &mut #inner_ty| Some(v),
1180                                        ),
1181                                    )
1182                                }
1183                            });
1184                        }
1185                        (WrapperKind::ArcRwLock, Some(inner_ty)) => {
1186                            // For Arc<parking_lot::RwLock<T>> (requires rust-key-paths "parking_lot" feature)
1187                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1188                            tokens.extend(quote! {
1189                                #[inline(always)]
1190                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1191                                    rust_key_paths::Kp::new(
1192                                        |root: &#name| Some(&root.#field_ident),
1193                                        |root: &mut #name| Some(&mut root.#field_ident),
1194                                    )
1195                                }
1196                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, #ty, #inner_ty> {
1197                                    rust_key_paths::lock::LockKp::new(
1198                                        rust_key_paths::Kp::new(
1199                                            |root: &#name| Some(&root.#field_ident),
1200                                            |root: &mut #name| Some(&mut root.#field_ident),
1201                                        ),
1202                                        rust_key_paths::lock::ParkingLotRwLockAccess::new(),
1203                                        rust_key_paths::Kp::new(
1204                                            |v: &#inner_ty| Some(v),
1205                                            |v: &mut #inner_ty| Some(v),
1206                                        ),
1207                                    )
1208                                }
1209                            });
1210                        }
1211                        (WrapperKind::ArcMutex, Some(inner_ty)) => {
1212                            // For Arc<parking_lot::Mutex<T>> (requires rust-key-paths "parking_lot" feature)
1213                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1214                            tokens.extend(quote! {
1215                                #[inline(always)]
1216                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1217                                    rust_key_paths::Kp::new(
1218                                        |root: &#name| Some(&root.#field_ident),
1219                                        |root: &mut #name| Some(&mut root.#field_ident),
1220                                    )
1221                                }
1222                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, #ty, #inner_ty> {
1223                                    rust_key_paths::lock::LockKp::new(
1224                                        rust_key_paths::Kp::new(
1225                                            |root: &#name| Some(&root.#field_ident),
1226                                            |root: &mut #name| Some(&mut root.#field_ident),
1227                                        ),
1228                                        rust_key_paths::lock::ParkingLotMutexAccess::new(),
1229                                        rust_key_paths::Kp::new(
1230                                            |v: &#inner_ty| Some(v),
1231                                            |v: &mut #inner_ty| Some(v),
1232                                        ),
1233                                    )
1234                                }
1235                            });
1236                        }
1237                        (WrapperKind::Mutex, Some(_inner_ty))
1238                        | (WrapperKind::StdMutex, Some(_inner_ty)) => {
1239                            // For Mutex<T>, return keypath to container
1240                            tokens.extend(quote! {
1241                                #[inline(always)]
1242                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1243                                    rust_key_paths::Kp::new(
1244                                        |root: &#name| Some(&root.#field_ident),
1245                                        |root: &mut #name| Some(&mut root.#field_ident),
1246                                    )
1247                                }
1248                            });
1249                        }
1250                        (WrapperKind::RwLock, Some(_inner_ty))
1251                        | (WrapperKind::StdRwLock, Some(_inner_ty)) => {
1252                            // For RwLock<T>, return keypath to container
1253                            tokens.extend(quote! {
1254                                #[inline(always)]
1255                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1256                                    rust_key_paths::Kp::new(
1257                                        |root: &#name| Some(&root.#field_ident),
1258                                        |root: &mut #name| Some(&mut root.#field_ident),
1259                                    )
1260                                }
1261                            });
1262                        }
1263                        (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
1264                            let kp_async_fn = format_ident!("{}_async", field_ident);
1265                            tokens.extend(quote! {
1266                                #[inline(always)]
1267                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1268                                    rust_key_paths::Kp::new(
1269                                        |root: &#name| Some(&root.#field_ident),
1270                                        |root: &mut #name| Some(&mut root.#field_ident),
1271                                    )
1272                                }
1273                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #ty, #inner_ty> {
1274                                    rust_key_paths::async_lock::AsyncLockKp::new(
1275                                        rust_key_paths::Kp::new(
1276                                            |root: &#name| Some(&root.#field_ident),
1277                                            |root: &mut #name| Some(&mut root.#field_ident),
1278                                        ),
1279                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
1280                                        rust_key_paths::Kp::new(
1281                                            |v: &#inner_ty| Some(v),
1282                                            |v: &mut #inner_ty| Some(v),
1283                                        ),
1284                                    )
1285                                }
1286                            });
1287                        }
1288                        (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
1289                            let kp_async_fn = format_ident!("{}_async", field_ident);
1290                            tokens.extend(quote! {
1291                                #[inline(always)]
1292                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1293                                    rust_key_paths::Kp::new(
1294                                        |root: &#name| Some(&root.#field_ident),
1295                                        |root: &mut #name| Some(&mut root.#field_ident),
1296                                    )
1297                                }
1298                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #ty, #inner_ty> {
1299                                    rust_key_paths::async_lock::AsyncLockKp::new(
1300                                        rust_key_paths::Kp::new(
1301                                            |root: &#name| Some(&root.#field_ident),
1302                                            |root: &mut #name| Some(&mut root.#field_ident),
1303                                        ),
1304                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
1305                                        rust_key_paths::Kp::new(
1306                                            |v: &#inner_ty| Some(v),
1307                                            |v: &mut #inner_ty| Some(v),
1308                                        ),
1309                                    )
1310                                }
1311                            });
1312                        }
1313                        (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
1314                            let kp_async_fn = format_ident!("{}_async", field_ident);
1315                            tokens.extend(quote! {
1316                                #[inline(always)]
1317                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1318                                    rust_key_paths::Kp::new(
1319                                        |root: &#name| Some(&root.#field_ident),
1320                                        |root: &mut #name| Some(&mut root.#field_ident),
1321                                    )
1322                                }
1323                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
1324                                    rust_key_paths::async_lock::AsyncLockKp::new(
1325                                        rust_key_paths::Kp::new(
1326                                            |root: &#name| root.#field_ident.as_ref(),
1327                                            |root: &mut #name| root.#field_ident.as_mut(),
1328                                        ),
1329                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
1330                                        rust_key_paths::Kp::new(
1331                                            |v: &#inner_ty| Some(v),
1332                                            |v: &mut #inner_ty| Some(v),
1333                                        ),
1334                                    )
1335                                }
1336                            });
1337                        }
1338                        (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
1339                            let kp_async_fn = format_ident!("{}_async", field_ident);
1340                            tokens.extend(quote! {
1341                                #[inline(always)]
1342                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1343                                    rust_key_paths::Kp::new(
1344                                        |root: &#name| Some(&root.#field_ident),
1345                                        |root: &mut #name| Some(&mut root.#field_ident),
1346                                    )
1347                                }
1348                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
1349                                    rust_key_paths::async_lock::AsyncLockKp::new(
1350                                        rust_key_paths::Kp::new(
1351                                            |root: &#name| root.#field_ident.as_ref(),
1352                                            |root: &mut #name| root.#field_ident.as_mut(),
1353                                        ),
1354                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
1355                                        rust_key_paths::Kp::new(
1356                                            |v: &#inner_ty| Some(v),
1357                                            |v: &mut #inner_ty| Some(v),
1358                                        ),
1359                                    )
1360                                }
1361                            });
1362                        }
1363                        (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
1364                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1365                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1366                            tokens.extend(quote! {
1367                                #[inline(always)]
1368                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1369                                    rust_key_paths::Kp::new(
1370                                        |root: &#name| Some(&root.#field_ident),
1371                                        |root: &mut #name| Some(&mut root.#field_ident),
1372                                    )
1373                                }
1374                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::Mutex<#inner_ty>>> {
1375                                    rust_key_paths::Kp::new(
1376                                        |root: &#name| root.#field_ident.as_ref(),
1377                                        |root: &mut #name| root.#field_ident.as_mut(),
1378                                    )
1379                                }
1380                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpArcMutexFor<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, #inner_ty> {
1381                                    rust_key_paths::lock::LockKp::new(
1382                                        rust_key_paths::Kp::new(
1383                                            |root: &#name| root.#field_ident.as_ref(),
1384                                            |root: &mut #name| root.#field_ident.as_mut(),
1385                                        ),
1386                                        rust_key_paths::lock::ArcMutexAccess::new(),
1387                                        rust_key_paths::Kp::new(
1388                                            |v: &#inner_ty| Some(v),
1389                                            |v: &mut #inner_ty| Some(v),
1390                                        ),
1391                                    )
1392                                }
1393                            });
1394                        }
1395                        (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
1396                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1397                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1398                            tokens.extend(quote! {
1399                                #[inline(always)]
1400                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1401                                    rust_key_paths::Kp::new(
1402                                        |root: &#name| Some(&root.#field_ident),
1403                                        |root: &mut #name| Some(&mut root.#field_ident),
1404                                    )
1405                                }
1406                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>> {
1407                                    rust_key_paths::Kp::new(
1408                                        |root: &#name| root.#field_ident.as_ref(),
1409                                        |root: &mut #name| root.#field_ident.as_mut(),
1410                                    )
1411                                }
1412                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, #inner_ty> {
1413                                    rust_key_paths::lock::LockKp::new(
1414                                        rust_key_paths::Kp::new(
1415                                            |root: &#name| root.#field_ident.as_ref(),
1416                                            |root: &mut #name| root.#field_ident.as_mut(),
1417                                        ),
1418                                        rust_key_paths::lock::ParkingLotMutexAccess::new(),
1419                                        rust_key_paths::Kp::new(
1420                                            |v: &#inner_ty| Some(v),
1421                                            |v: &mut #inner_ty| Some(v),
1422                                        ),
1423                                    )
1424                                }
1425                            });
1426                        }
1427                        (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
1428                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1429                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1430                            tokens.extend(quote! {
1431                                #[inline(always)]
1432                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1433                                    rust_key_paths::Kp::new(
1434                                        |root: &#name| Some(&root.#field_ident),
1435                                        |root: &mut #name| Some(&mut root.#field_ident),
1436                                    )
1437                                }
1438                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::RwLock<#inner_ty>>> {
1439                                    rust_key_paths::Kp::new(
1440                                        |root: &#name| root.#field_ident.as_ref(),
1441                                        |root: &mut #name| root.#field_ident.as_mut(),
1442                                    )
1443                                }
1444                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, #inner_ty> {
1445                                    rust_key_paths::lock::LockKp::new(
1446                                        rust_key_paths::Kp::new(
1447                                            |root: &#name| root.#field_ident.as_ref(),
1448                                            |root: &mut #name| root.#field_ident.as_mut(),
1449                                        ),
1450                                        rust_key_paths::lock::ArcRwLockAccess::new(),
1451                                        rust_key_paths::Kp::new(
1452                                            |v: &#inner_ty| Some(v),
1453                                            |v: &mut #inner_ty| Some(v),
1454                                        ),
1455                                    )
1456                                }
1457                            });
1458                        }
1459                        (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
1460                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1461                            let kp_lock_fn = format_ident!("{}_lock", field_ident);
1462                            tokens.extend(quote! {
1463                                #[inline(always)]
1464                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1465                                    rust_key_paths::Kp::new(
1466                                        |root: &#name| Some(&root.#field_ident),
1467                                        |root: &mut #name| Some(&mut root.#field_ident),
1468                                    )
1469                                }
1470                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>> {
1471                                    rust_key_paths::Kp::new(
1472                                        |root: &#name| root.#field_ident.as_ref(),
1473                                        |root: &mut #name| root.#field_ident.as_mut(),
1474                                    )
1475                                }
1476                                pub fn #kp_lock_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, #inner_ty> {
1477                                    rust_key_paths::lock::LockKp::new(
1478                                        rust_key_paths::Kp::new(
1479                                            |root: &#name| root.#field_ident.as_ref(),
1480                                            |root: &mut #name| root.#field_ident.as_mut(),
1481                                        ),
1482                                        rust_key_paths::lock::ParkingLotRwLockAccess::new(),
1483                                        rust_key_paths::Kp::new(
1484                                            |v: &#inner_ty| Some(v),
1485                                            |v: &mut #inner_ty| Some(v),
1486                                        ),
1487                                    )
1488                                }
1489                            });
1490                        }
1491                        (WrapperKind::OptionStdMutex, Some(inner_ty))
1492                        | (WrapperKind::OptionMutex, Some(inner_ty)) => {
1493                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1494                            tokens.extend(quote! {
1495                                #[inline(always)]
1496                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1497                                    rust_key_paths::Kp::new(
1498                                        |root: &#name| Some(&root.#field_ident),
1499                                        |root: &mut #name| Some(&mut root.#field_ident),
1500                                    )
1501                                }
1502                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Mutex<#inner_ty>> {
1503                                    rust_key_paths::Kp::new(
1504                                        |root: &#name| root.#field_ident.as_ref(),
1505                                        |root: &mut #name| root.#field_ident.as_mut(),
1506                                    )
1507                                }
1508                            });
1509                        }
1510                        (WrapperKind::OptionStdRwLock, Some(inner_ty))
1511                        | (WrapperKind::OptionRwLock, Some(inner_ty)) => {
1512                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
1513                            tokens.extend(quote! {
1514                                #[inline(always)]
1515                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1516                                    rust_key_paths::Kp::new(
1517                                        |root: &#name| Some(&root.#field_ident),
1518                                        |root: &mut #name| Some(&mut root.#field_ident),
1519                                    )
1520                                }
1521                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::RwLock<#inner_ty>> {
1522                                    rust_key_paths::Kp::new(
1523                                        |root: &#name| root.#field_ident.as_ref(),
1524                                        |root: &mut #name| root.#field_ident.as_mut(),
1525                                    )
1526                                }
1527                            });
1528                        }
1529                        (WrapperKind::Weak, Some(_inner_ty)) => {
1530                            // For Weak<T>, return keypath to container
1531                            tokens.extend(quote! {
1532                                #[inline(always)]
1533                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1534                                    rust_key_paths::Kp::new(
1535                                        |root: &#name| Some(&root.#field_ident),
1536                                        |_root: &mut #name| None, // Weak doesn't support mutable access
1537                                    )
1538                                }
1539                            });
1540                        }
1541                        (WrapperKind::Atomic, None | Some(_)) => {
1542                            // For atomic types: return keypath to the atomic (user calls .load()/.store())
1543                            tokens.extend(quote! {
1544                                #[inline(always)]
1545                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1546                                    rust_key_paths::Kp::new(
1547                                        |root: &#name| Some(&root.#field_ident),
1548                                        |root: &mut #name| Some(&mut root.#field_ident),
1549                                    )
1550                                }
1551                            });
1552                        }
1553                        (WrapperKind::OptionAtomic, Some(inner_ty)) => {
1554                            tokens.extend(quote! {
1555                                #[inline(always)]
1556                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1557                                    rust_key_paths::Kp::new(
1558                                        |root: &#name| root.#field_ident.as_ref(),
1559                                        |root: &mut #name| root.#field_ident.as_mut(),
1560                                    )
1561                                }
1562                            });
1563                        }
1564                        (WrapperKind::String, None) => {
1565                            tokens.extend(quote! {
1566                                #[inline(always)]
1567                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1568                                    rust_key_paths::Kp::new(
1569                                        |root: &#name| Some(&root.#field_ident),
1570                                        |root: &mut #name| Some(&mut root.#field_ident),
1571                                    )
1572                                }
1573                            });
1574                        }
1575                        (WrapperKind::OptionString, None) => {
1576                            tokens.extend(quote! {
1577                                #[inline(always)]
1578                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, std::string::String> {
1579                                    rust_key_paths::Kp::new(
1580                                        |root: &#name| root.#field_ident.as_ref(),
1581                                        |root: &mut #name| root.#field_ident.as_mut(),
1582                                    )
1583                                }
1584                            });
1585                        }
1586                        (WrapperKind::Cell, Some(_inner_ty)) => {
1587                            tokens.extend(quote! {
1588                                #[inline(always)]
1589                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1590                                    rust_key_paths::Kp::new(
1591                                        |root: &#name| Some(&root.#field_ident),
1592                                        |root: &mut #name| Some(&mut root.#field_ident),
1593                                    )
1594                                }
1595                            });
1596                        }
1597                        (WrapperKind::RefCell, Some(_inner_ty)) => {
1598                            tokens.extend(quote! {
1599                                #[inline(always)]
1600                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1601                                    rust_key_paths::Kp::new(
1602                                        |root: &#name| Some(&root.#field_ident),
1603                                        |root: &mut #name| Some(&mut root.#field_ident),
1604                                    )
1605                                }
1606                            });
1607                        }
1608                        (WrapperKind::OnceCell, Some(inner_ty)) => {
1609                            // OnceLock/OnceCell: keypath to inner value; get = .get() -> Option<&T>, set = None
1610                            tokens.extend(quote! {
1611                                #[inline(always)]
1612                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1613                                    rust_key_paths::Kp::new(
1614                                        |root: &#name| root.#field_ident.get(),
1615                                        |_root: &mut #name| None,
1616                                    )
1617                                }
1618                            });
1619                        }
1620                        (WrapperKind::Lazy, Some(inner_ty)) => {
1621                            // Lazy/LazyLock: keypath to inner value; get = .get() -> &T wrapped in Some, set = None
1622                            tokens.extend(quote! {
1623                                #[inline(always)]
1624                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1625                                    rust_key_paths::Kp::new(
1626                                        |root: &#name| Some(root.#field_ident.get()),
1627                                        |_root: &mut #name| None,
1628                                    )
1629                                }
1630                            });
1631                        }
1632                        (WrapperKind::PhantomData, Some(_inner_ty)) => {
1633                            tokens.extend(quote! {
1634                                #[inline(always)]
1635                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1636                                    rust_key_paths::Kp::new(
1637                                        |root: &#name| Some(&root.#field_ident),
1638                                        |root: &mut #name| Some(&mut root.#field_ident),
1639                                    )
1640                                }
1641                            });
1642                        }
1643                        (WrapperKind::Range, Some(_inner_ty)) => {
1644                            tokens.extend(quote! {
1645                                #[inline(always)]
1646                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1647                                    rust_key_paths::Kp::new(
1648                                        |root: &#name| Some(&root.#field_ident),
1649                                        |root: &mut #name| Some(&mut root.#field_ident),
1650                                    )
1651                                }
1652                            });
1653                        }
1654                        (WrapperKind::OptionCell, Some(_inner_ty)) => {
1655                            tokens.extend(quote! {
1656                                #[inline(always)]
1657                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1658                                    rust_key_paths::Kp::new(
1659                                        |root: &#name| Some(&root.#field_ident),
1660                                        |root: &mut #name| Some(&mut root.#field_ident),
1661                                    )
1662                                }
1663                            });
1664                        }
1665                        (WrapperKind::OptionRefCell, Some(_inner_ty)) => {
1666                            tokens.extend(quote! {
1667                                #[inline(always)]
1668                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1669                                    rust_key_paths::Kp::new(
1670                                        |root: &#name| Some(&root.#field_ident),
1671                                        |root: &mut #name| Some(&mut root.#field_ident),
1672                                    )
1673                                }
1674                            });
1675                        }
1676                        (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
1677                            tokens.extend(quote! {
1678                                #[inline(always)]
1679                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1680                                    rust_key_paths::Kp::new(
1681                                        |root: &#name| root.#field_ident.as_ref().and_then(|c| c.get()),
1682                                        |_root: &mut #name| None,
1683                                    )
1684                                }
1685                            });
1686                        }
1687                        (WrapperKind::OptionLazy, Some(inner_ty)) => {
1688                            tokens.extend(quote! {
1689                                #[inline(always)]
1690                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1691                                    rust_key_paths::Kp::new(
1692                                        |root: &#name| root.#field_ident.as_ref().map(|c| c.get()),
1693                                        |_root: &mut #name| None,
1694                                    )
1695                                }
1696                            });
1697                        }
1698                        (WrapperKind::OptionPhantomData, Some(_inner_ty)) => {
1699                            tokens.extend(quote! {
1700                                #[inline(always)]
1701                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1702                                    rust_key_paths::Kp::new(
1703                                        |root: &#name| Some(&root.#field_ident),
1704                                        |root: &mut #name| Some(&mut root.#field_ident),
1705                                    )
1706                                }
1707                            });
1708                        }
1709                        (WrapperKind::OptionRange, Some(_inner_ty)) => {
1710                            tokens.extend(quote! {
1711                                #[inline(always)]
1712                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1713                                    rust_key_paths::Kp::new(
1714                                        |root: &#name| Some(&root.#field_ident),
1715                                        |root: &mut #name| Some(&mut root.#field_ident),
1716                                    )
1717                                }
1718                            });
1719                        }
1720                        (WrapperKind::Reference, Some(_inner_ty)) => {
1721                            // For reference types (&T, &str, &[T]): read-only, setter returns None
1722                            tokens.extend(quote! {
1723                                #[inline(always)]
1724                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1725                                    rust_key_paths::Kp::new(
1726                                        |root: &#name| Some(&root.#field_ident),
1727                                        |_root: &mut #name| None, // references: read-only
1728                                    )
1729                                }
1730                            });
1731                        }
1732                        (WrapperKind::None, None) => {
1733                            // For basic types, direct access
1734                            tokens.extend(quote! {
1735                                #[inline(always)]
1736                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1737                                    rust_key_paths::Kp::new(
1738                                        |root: &#name| Some(&root.#field_ident),
1739                                        |root: &mut #name| Some(&mut root.#field_ident),
1740                                    )
1741                                }
1742                            });
1743                        }
1744                        _ => {
1745                            // For unknown/complex nested types, return keypath to field itself
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                    }
1757                }
1758                
1759                tokens
1760            }
1761            Fields::Unnamed(unnamed) => {
1762                let mut tokens = proc_macro2::TokenStream::new();
1763
1764                // Generate identity methods for the tuple struct
1765                tokens.extend(quote! {
1766                    /// Returns a generic identity keypath for this type
1767                    #[inline(always)]
1768                    pub fn identity_typed<Root, MutRoot>() -> rust_key_paths::Kp<
1769                        #name,
1770                        #name,
1771                        Root,
1772                        Root,
1773                        MutRoot,
1774                        MutRoot,
1775                        fn(Root) -> Option<Root>,
1776                        fn(MutRoot) -> Option<MutRoot>,
1777                    >
1778                    where
1779                        Root: std::borrow::Borrow<#name>,
1780                        MutRoot: std::borrow::BorrowMut<#name>,
1781                    {
1782                        rust_key_paths::Kp::new(
1783                            |r: Root| Some(r),
1784                            |r: MutRoot| Some(r)
1785                        )
1786                    }
1787
1788                    /// Returns a simple identity keypath for this type
1789                    #[inline(always)]
1790                    pub fn identity() -> rust_key_paths::KpType<'static, #name, #name> {
1791                        rust_key_paths::Kp::new(
1792                            |r: &#name| Some(r),
1793                            |r: &mut #name| Some(r)
1794                        )
1795                    }
1796                });
1797
1798                for (idx, field) in unnamed.unnamed.iter().enumerate() {
1799                    let idx_lit = syn::Index::from(idx);
1800                    let ty = &field.ty;
1801                    // Centralized keypath method names for tuple fields – change here to adjust for all types
1802                    let kp_fn = format_ident!("f{}", idx);
1803                    let kp_at_fn = format_ident!("f{}_at", idx);
1804
1805                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
1806
1807                    match (kind, inner_ty.clone()) {
1808                        (WrapperKind::Option, Some(inner_ty)) => {
1809                            tokens.extend(quote! {
1810                                #[inline(always)]
1811                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1812                                    rust_key_paths::Kp::new(
1813                                        |root: &#name| root.#idx_lit.as_ref(),
1814                                        |root: &mut #name| root.#idx_lit.as_mut(),
1815                                    )
1816                                }
1817                            });
1818                        }
1819                        (WrapperKind::OptionBox, Some(inner_ty)) => {
1820                            tokens.extend(quote! {
1821                                #[inline(always)]
1822                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1823                                    rust_key_paths::Kp::new(
1824                                        |root: &#name| root.#idx_lit.as_deref(),
1825                                        |root: &mut #name| root.#idx_lit.as_deref_mut(),
1826                                    )
1827                                }
1828                            });
1829                        }
1830                        (WrapperKind::OptionRc, Some(inner_ty)) => {
1831                            tokens.extend(quote! {
1832                                #[inline(always)]
1833                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1834                                    rust_key_paths::Kp::new(
1835                                        |root: &#name| root.#idx_lit.as_deref(),
1836                                        |root: &mut #name| root.#idx_lit.as_mut().and_then(std::rc::Rc::get_mut),
1837                                    )
1838                                }
1839                            });
1840                        }
1841                        (WrapperKind::OptionArc, Some(inner_ty)) => {
1842                            tokens.extend(quote! {
1843                                #[inline(always)]
1844                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1845                                    rust_key_paths::Kp::new(
1846                                        |root: &#name| root.#idx_lit.as_deref(),
1847                                        |root: &mut #name| root.#idx_lit.as_mut().and_then(std::sync::Arc::get_mut),
1848                                    )
1849                                }
1850                            });
1851                        }
1852                        (WrapperKind::OptionVecDeque, Some(_inner_ty))
1853                        | (WrapperKind::OptionLinkedList, Some(_inner_ty))
1854                        | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
1855                        | (WrapperKind::OptionHashSet, Some(_inner_ty))
1856                        | (WrapperKind::OptionBTreeSet, Some(_inner_ty))
1857                        | (WrapperKind::OptionResult, Some(_inner_ty))
1858                        | (WrapperKind::OptionBTreeMap, Some(_inner_ty)) => {
1859                            tokens.extend(quote! {
1860                                #[inline(always)]
1861                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1862                                    rust_key_paths::Kp::new(
1863                                        |root: &#name| Some(&root.#idx_lit),
1864                                        |root: &mut #name| Some(&mut root.#idx_lit),
1865                                    )
1866                                }
1867                            });
1868                        }
1869                        (WrapperKind::Vec, Some(inner_ty)) => {
1870                            tokens.extend(quote! {
1871                                #[inline(always)]
1872                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1873                                    rust_key_paths::Kp::new(
1874                                        |root: &#name| Some(&root.#idx_lit),
1875                                        |root: &mut #name| Some(&mut root.#idx_lit),
1876                                    )
1877                                }
1878                                #[inline(always)]
1879                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1880                                    rust_key_paths::Kp::new(
1881                                        Box::new(move |root: &#name| root.#idx_lit.get(index)),
1882                                        Box::new(move |root: &mut #name| root.#idx_lit.get_mut(index)),
1883                                    )
1884                                }
1885                            });
1886                        }
1887                        (WrapperKind::HashMap, Some(inner_ty)) => {
1888                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
1889                                tokens.extend(quote! {
1890                                    #[inline(always)]
1891                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1892                                        rust_key_paths::Kp::new(
1893                                            |root: &#name| Some(&root.#idx_lit),
1894                                            |root: &mut #name| Some(&mut root.#idx_lit),
1895                                        )
1896                                    }
1897                                    #[inline(always)]
1898                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1899                                    where
1900                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
1901                                    {
1902                                        let key2 = key.clone();
1903                                        rust_key_paths::Kp::new(
1904                                            Box::new(move |root: &#name| root.#idx_lit.get(&key)),
1905                                            Box::new(move |root: &mut #name| root.#idx_lit.get_mut(&key2)),
1906                                        )
1907                                    }
1908                                });
1909                            } else {
1910                                tokens.extend(quote! {
1911                                    #[inline(always)]
1912                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1913                                        rust_key_paths::Kp::new(
1914                                            |root: &#name| Some(&root.#idx_lit),
1915                                            |root: &mut #name| Some(&mut root.#idx_lit),
1916                                        )
1917                                    }
1918                                });
1919                            }
1920                        }
1921                        (WrapperKind::BTreeMap, Some(inner_ty)) | (WrapperKind::BTreeMapOption, Some(inner_ty)) => {
1922                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
1923                                tokens.extend(quote! {
1924                                    #[inline(always)]
1925                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1926                                        rust_key_paths::Kp::new(
1927                                            |root: &#name| Some(&root.#idx_lit),
1928                                            |root: &mut #name| Some(&mut root.#idx_lit),
1929                                        )
1930                                    }
1931                                    #[inline(always)]
1932                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1933                                    where
1934                                        #key_ty: Clone + Ord + 'static,
1935                                    {
1936                                        let key2 = key.clone();
1937                                        rust_key_paths::Kp::new(
1938                                            Box::new(move |root: &#name| root.#idx_lit.get(&key)),
1939                                            Box::new(move |root: &mut #name| root.#idx_lit.get_mut(&key2)),
1940                                        )
1941                                    }
1942                                });
1943                            } else {
1944                                tokens.extend(quote! {
1945                                    #[inline(always)]
1946                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1947                                        rust_key_paths::Kp::new(
1948                                            |root: &#name| Some(&root.#idx_lit),
1949                                            |root: &mut #name| Some(&mut root.#idx_lit),
1950                                        )
1951                                    }
1952                                });
1953                            }
1954                        }
1955                        (WrapperKind::Box, Some(inner_ty)) => {
1956                            // Box: deref to inner (returns &T / &mut T)
1957                            tokens.extend(quote! {
1958                                #[inline(always)]
1959                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
1960                                    rust_key_paths::Kp::new(
1961                                        |root: &#name| Some(&*root.#idx_lit),
1962                                        |root: &mut #name| Some(&mut *root.#idx_lit),
1963                                    )
1964                                }
1965                            });
1966                        }
1967                        (WrapperKind::Pin, Some(inner_ty)) => {
1968                            let kp_inner_fn = format_ident!("{}_inner", kp_fn);
1969                            tokens.extend(quote! {
1970                                #[inline(always)]
1971                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1972                                    rust_key_paths::Kp::new(
1973                                        |root: &#name| Some(&root.#idx_lit),
1974                                        |root: &mut #name| Some(&mut root.#idx_lit),
1975                                    )
1976                                }
1977                                #[inline(always)]
1978                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
1979                                where #inner_ty: std::marker::Unpin
1980                                {
1981                                    rust_key_paths::Kp::new(
1982                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#idx_lit).get_ref()),
1983                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#idx_lit).get_mut()),
1984                                    )
1985                                }
1986                            });
1987                        }
1988                        (WrapperKind::PinBox, Some(inner_ty)) => {
1989                            let kp_inner_fn = format_ident!("{}_inner", kp_fn);
1990                            tokens.extend(quote! {
1991                                #[inline(always)]
1992                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
1993                                    rust_key_paths::Kp::new(
1994                                        |root: &#name| Some(&root.#idx_lit),
1995                                        |root: &mut #name| Some(&mut root.#idx_lit),
1996                                    )
1997                                }
1998                                #[inline(always)]
1999                                pub fn #kp_inner_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2000                                where #inner_ty: std::marker::Unpin
2001                                {
2002                                    rust_key_paths::Kp::new(
2003                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#idx_lit).get_ref()),
2004                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#idx_lit).get_mut()),
2005                                    )
2006                                }
2007                            });
2008                        }
2009                        (WrapperKind::Rc, Some(inner_ty)) => {
2010                            tokens.extend(quote! {
2011                                #[inline(always)]
2012                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2013                                    rust_key_paths::Kp::new(
2014                                        |root: &#name| Some(root.#idx_lit.as_ref()),
2015                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#idx_lit),
2016                                    )
2017                                }
2018                            });
2019                        }
2020                        (WrapperKind::Arc, Some(inner_ty)) => {
2021                            tokens.extend(quote! {
2022                                #[inline(always)]
2023                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2024                                    rust_key_paths::Kp::new(
2025                                        |root: &#name| Some(root.#idx_lit.as_ref()),
2026                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#idx_lit),
2027                                    )
2028                                }
2029                            });
2030                        }
2031                        
2032                        (WrapperKind::Cow, Some(inner_ty)) => {
2033                            tokens.extend(quote! {
2034                                #[inline(always)]
2035                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2036                                    rust_key_paths::Kp::new(
2037                                        |root: &#name| Some(root.#idx_lit.as_ref()),
2038                                        |root: &mut #name| Some(root.#idx_lit.to_mut()),
2039                                    )
2040                                }
2041                            });
2042                        }
2043                        
2044                        (WrapperKind::OptionCow, Some(inner_ty)) => {
2045                            tokens.extend(quote! {
2046                                #[inline(always)]
2047                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2048                                    rust_key_paths::Kp::new(
2049                                        |root: &#name| root.#idx_lit.as_ref().map(|c| c.as_ref()),
2050                                        |root: &mut #name| root.#idx_lit.as_mut().map(|c| c.to_mut()),
2051                                    )
2052                                }
2053                            });
2054                        }
2055                        (WrapperKind::OptionTagged, Some(inner_ty)) => {
2056                            tokens.extend(quote! {
2057                                #[inline(always)]
2058                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2059                                    rust_key_paths::Kp::new(
2060                                        |root: &#name| root.#idx_lit.as_ref().map(|t| std::ops::Deref::deref(t)),
2061                                        |root: &mut #name| root.#idx_lit.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
2062                                    )
2063                                }
2064                            });
2065                        }
2066                        (WrapperKind::OptionReference, Some(inner_ty)) => {
2067                            tokens.extend(quote! {
2068                                #[inline(always)]
2069                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2070                                    rust_key_paths::Kp::new(
2071                                        |root: &#name| root.#idx_lit.as_ref(),
2072                                        |_root: &mut #name| None,
2073                                    )
2074                                }
2075                            });
2076                        }
2077                        (WrapperKind::HashSet, Some(inner_ty)) | (WrapperKind::HashSetOption, Some(inner_ty)) => {
2078                            let kp_at_fn = format_ident!("f{}_at", idx);
2079
2080                            tokens.extend(quote! {
2081                                #[inline(always)]
2082                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2083                                    rust_key_paths::Kp::new(
2084                                        |root: &#name| Some(&root.#idx_lit),
2085                                        |root: &mut #name| Some(&mut root.#idx_lit),
2086                                    )
2087                                }
2088
2089                                /// _at: check if element exists and get reference.
2090                                /// HashSet does not allow mutable element access (would break hash invariant).
2091                                #[inline(always)]
2092                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
2093                                where
2094                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
2095                                {
2096                                    rust_key_paths::Kp::new(
2097                                        Box::new(move |root: &#name| root.#idx_lit.get(&key)),
2098                                        Box::new(move |_root: &mut #name| None),
2099                                    )
2100                                }
2101                            });
2102                        }
2103                        (WrapperKind::BTreeSet, Some(inner_ty)) | (WrapperKind::BTreeSetOption, Some(inner_ty)) => {
2104                            let kp_at_fn = format_ident!("f{}_at", idx);
2105
2106                            tokens.extend(quote! {
2107                                #[inline(always)]
2108                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2109                                    rust_key_paths::Kp::new(
2110                                        |root: &#name| Some(&root.#idx_lit),
2111                                        |root: &mut #name| Some(&mut root.#idx_lit),
2112                                    )
2113                                }
2114
2115                                /// _at: check if element exists and get reference.
2116                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
2117                                #[inline(always)]
2118                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
2119                                where
2120                                    #inner_ty: Clone + Ord + 'static,
2121                                {
2122                                    rust_key_paths::Kp::new(
2123                                        Box::new(move |root: &#name| root.#idx_lit.get(&key)),
2124                                        Box::new(move |_root: &mut #name| None),
2125                                    )
2126                                }
2127                            });
2128                        }
2129                        (WrapperKind::VecDeque, Some(inner_ty)) | (WrapperKind::VecDequeOption, Some(inner_ty)) => {
2130                            tokens.extend(quote! {
2131                                #[inline(always)]
2132                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2133                                    rust_key_paths::Kp::new(
2134                                        |root: &#name| Some(&root.#idx_lit),
2135                                        |root: &mut #name| Some(&mut root.#idx_lit),
2136                                    )
2137                                }
2138                                #[inline(always)]
2139                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
2140                                    rust_key_paths::Kp::new(
2141                                        Box::new(move |root: &#name| root.#idx_lit.get(index)),
2142                                        Box::new(move |root: &mut #name| root.#idx_lit.get_mut(index)),
2143                                    )
2144                                }
2145                            });
2146                        }
2147                        (WrapperKind::LinkedList, Some(_inner_ty)) | (WrapperKind::LinkedListOption, Some(_inner_ty)) => {
2148                            tokens.extend(quote! {
2149                                #[inline(always)]
2150                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2151                                    rust_key_paths::Kp::new(
2152                                        |root: &#name| Some(&root.#idx_lit),
2153                                        |root: &mut #name| Some(&mut root.#idx_lit),
2154                                    )
2155                                }
2156                            });
2157                        }
2158                        (WrapperKind::BinaryHeap, Some(_inner_ty)) | (WrapperKind::BinaryHeapOption, Some(_inner_ty)) => {
2159                            tokens.extend(quote! {
2160                                #[inline(always)]
2161                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2162                                    rust_key_paths::Kp::new(
2163                                        |root: &#name| Some(&root.#idx_lit),
2164                                        |root: &mut #name| Some(&mut root.#idx_lit),
2165                                    )
2166                                }
2167                            });
2168                        }
2169                        (WrapperKind::Result, Some(inner_ty)) => {
2170                            tokens.extend(quote! {
2171                                #[inline(always)]
2172                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2173                                    rust_key_paths::Kp::new(
2174                                        |root: &#name| root.#idx_lit.as_ref().ok(),
2175                                        |root: &mut #name| root.#idx_lit.as_mut().ok(),
2176                                    )
2177                                }
2178                            });
2179                        }
2180                        (WrapperKind::Mutex, Some(_inner_ty))
2181                        | (WrapperKind::StdMutex, Some(_inner_ty)) => {
2182                            tokens.extend(quote! {
2183                                #[inline(always)]
2184                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2185                                    rust_key_paths::Kp::new(
2186                                        |root: &#name| Some(&root.#idx_lit),
2187                                        |root: &mut #name| Some(&mut root.#idx_lit),
2188                                    )
2189                                }
2190                            });
2191                        }
2192                        (WrapperKind::RwLock, Some(_inner_ty))
2193                        | (WrapperKind::StdRwLock, Some(_inner_ty)) => {
2194                            tokens.extend(quote! {
2195                                #[inline(always)]
2196                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2197                                    rust_key_paths::Kp::new(
2198                                        |root: &#name| Some(&root.#idx_lit),
2199                                        |root: &mut #name| Some(&mut root.#idx_lit),
2200                                    )
2201                                }
2202                            });
2203                        }
2204                        (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
2205                            let kp_async_fn = format_ident!("f{}_async", idx);
2206                            tokens.extend(quote! {
2207                                #[inline(always)]
2208                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2209                                    rust_key_paths::Kp::new(
2210                                        |root: &#name| Some(&root.#idx_lit),
2211                                        |root: &mut #name| Some(&mut root.#idx_lit),
2212                                    )
2213                                }
2214                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #ty, #inner_ty> {
2215                                    rust_key_paths::async_lock::AsyncLockKp::new(
2216                                        rust_key_paths::Kp::new(
2217                                            |root: &#name| Some(&root.#idx_lit),
2218                                            |root: &mut #name| Some(&mut root.#idx_lit),
2219                                        ),
2220                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
2221                                        rust_key_paths::Kp::new(
2222                                            |v: &#inner_ty| Some(v),
2223                                            |v: &mut #inner_ty| Some(v),
2224                                        ),
2225                                    )
2226                                }
2227                            });
2228                        }
2229                        (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
2230                            let kp_async_fn = format_ident!("f{}_async", idx);
2231                            tokens.extend(quote! {
2232                                #[inline(always)]
2233                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2234                                    rust_key_paths::Kp::new(
2235                                        |root: &#name| Some(&root.#idx_lit),
2236                                        |root: &mut #name| Some(&mut root.#idx_lit),
2237                                    )
2238                                }
2239                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #ty, #inner_ty> {
2240                                    rust_key_paths::async_lock::AsyncLockKp::new(
2241                                        rust_key_paths::Kp::new(
2242                                            |root: &#name| Some(&root.#idx_lit),
2243                                            |root: &mut #name| Some(&mut root.#idx_lit),
2244                                        ),
2245                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
2246                                        rust_key_paths::Kp::new(
2247                                            |v: &#inner_ty| Some(v),
2248                                            |v: &mut #inner_ty| Some(v),
2249                                        ),
2250                                    )
2251                                }
2252                            });
2253                        }
2254                        (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
2255                            let kp_async_fn = format_ident!("f{}_async", idx);
2256                            tokens.extend(quote! {
2257                                #[inline(always)]
2258                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2259                                    rust_key_paths::Kp::new(
2260                                        |root: &#name| Some(&root.#idx_lit),
2261                                        |root: &mut #name| Some(&mut root.#idx_lit),
2262                                    )
2263                                }
2264                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
2265                                    rust_key_paths::async_lock::AsyncLockKp::new(
2266                                        rust_key_paths::Kp::new(
2267                                            |root: &#name| root.#idx_lit.as_ref(),
2268                                            |root: &mut #name| root.#idx_lit.as_mut(),
2269                                        ),
2270                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
2271                                        rust_key_paths::Kp::new(
2272                                            |v: &#inner_ty| Some(v),
2273                                            |v: &mut #inner_ty| Some(v),
2274                                        ),
2275                                    )
2276                                }
2277                            });
2278                        }
2279                        (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
2280                            let kp_async_fn = format_ident!("f{}_async", idx);
2281                            tokens.extend(quote! {
2282                                #[inline(always)]
2283                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2284                                    rust_key_paths::Kp::new(
2285                                        |root: &#name| Some(&root.#idx_lit),
2286                                        |root: &mut #name| Some(&mut root.#idx_lit),
2287                                    )
2288                                }
2289                                pub fn #kp_async_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
2290                                    rust_key_paths::async_lock::AsyncLockKp::new(
2291                                        rust_key_paths::Kp::new(
2292                                            |root: &#name| root.#idx_lit.as_ref(),
2293                                            |root: &mut #name| root.#idx_lit.as_mut(),
2294                                        ),
2295                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
2296                                        rust_key_paths::Kp::new(
2297                                            |v: &#inner_ty| Some(v),
2298                                            |v: &mut #inner_ty| Some(v),
2299                                        ),
2300                                    )
2301                                }
2302                            });
2303                        }
2304                        (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
2305                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2306                            tokens.extend(quote! {
2307                                #[inline(always)]
2308                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2309                                    rust_key_paths::Kp::new(
2310                                        |root: &#name| Some(&root.#idx_lit),
2311                                        |root: &mut #name| Some(&mut root.#idx_lit),
2312                                    )
2313                                }
2314                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::Mutex<#inner_ty>>> {
2315                                    rust_key_paths::Kp::new(
2316                                        |root: &#name| root.#idx_lit.as_ref(),
2317                                        |root: &mut #name| root.#idx_lit.as_mut(),
2318                                    )
2319                                }
2320                            });
2321                        }
2322                        (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
2323                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2324                            tokens.extend(quote! {
2325                                #[inline(always)]
2326                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2327                                    rust_key_paths::Kp::new(
2328                                        |root: &#name| Some(&root.#idx_lit),
2329                                        |root: &mut #name| Some(&mut root.#idx_lit),
2330                                    )
2331                                }
2332                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>> {
2333                                    rust_key_paths::Kp::new(
2334                                        |root: &#name| root.#idx_lit.as_ref(),
2335                                        |root: &mut #name| root.#idx_lit.as_mut(),
2336                                    )
2337                                }
2338                            });
2339                        }
2340                        (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
2341                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2342                            tokens.extend(quote! {
2343                                #[inline(always)]
2344                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2345                                    rust_key_paths::Kp::new(
2346                                        |root: &#name| Some(&root.#idx_lit),
2347                                        |root: &mut #name| Some(&mut root.#idx_lit),
2348                                    )
2349                                }
2350                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::RwLock<#inner_ty>>> {
2351                                    rust_key_paths::Kp::new(
2352                                        |root: &#name| root.#idx_lit.as_ref(),
2353                                        |root: &mut #name| root.#idx_lit.as_mut(),
2354                                    )
2355                                }
2356                            });
2357                        }
2358                        (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
2359                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2360                            tokens.extend(quote! {
2361                                #[inline(always)]
2362                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2363                                    rust_key_paths::Kp::new(
2364                                        |root: &#name| Some(&root.#idx_lit),
2365                                        |root: &mut #name| Some(&mut root.#idx_lit),
2366                                    )
2367                                }
2368                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>> {
2369                                    rust_key_paths::Kp::new(
2370                                        |root: &#name| root.#idx_lit.as_ref(),
2371                                        |root: &mut #name| root.#idx_lit.as_mut(),
2372                                    )
2373                                }
2374                            });
2375                        }
2376                        (WrapperKind::OptionStdMutex, Some(inner_ty))
2377                        | (WrapperKind::OptionMutex, Some(inner_ty)) => {
2378                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2379                            tokens.extend(quote! {
2380                                #[inline(always)]
2381                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2382                                    rust_key_paths::Kp::new(
2383                                        |root: &#name| Some(&root.#idx_lit),
2384                                        |root: &mut #name| Some(&mut root.#idx_lit),
2385                                    )
2386                                }
2387                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::Mutex<#inner_ty>> {
2388                                    rust_key_paths::Kp::new(
2389                                        |root: &#name| root.#idx_lit.as_ref(),
2390                                        |root: &mut #name| root.#idx_lit.as_mut(),
2391                                    )
2392                                }
2393                            });
2394                        }
2395                        (WrapperKind::OptionStdRwLock, Some(inner_ty))
2396                        | (WrapperKind::OptionRwLock, Some(inner_ty)) => {
2397                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
2398                            tokens.extend(quote! {
2399                                #[inline(always)]
2400                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2401                                    rust_key_paths::Kp::new(
2402                                        |root: &#name| Some(&root.#idx_lit),
2403                                        |root: &mut #name| Some(&mut root.#idx_lit),
2404                                    )
2405                                }
2406                                pub fn #kp_unlocked_fn() -> rust_key_paths::KpType<'static, #name, std::sync::RwLock<#inner_ty>> {
2407                                    rust_key_paths::Kp::new(
2408                                        |root: &#name| root.#idx_lit.as_ref(),
2409                                        |root: &mut #name| root.#idx_lit.as_mut(),
2410                                    )
2411                                }
2412                            });
2413                        }
2414                        (WrapperKind::Weak, Some(_inner_ty)) => {
2415                            tokens.extend(quote! {
2416                                #[inline(always)]
2417                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2418                                    rust_key_paths::Kp::new(
2419                                        |root: &#name| Some(&root.#idx_lit),
2420                                        |_root: &mut #name| None,
2421                                    )
2422                                }
2423                            });
2424                        }
2425                        (WrapperKind::Atomic, None | Some(_)) => {
2426                            tokens.extend(quote! {
2427                                #[inline(always)]
2428                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2429                                    rust_key_paths::Kp::new(
2430                                        |root: &#name| Some(&root.#idx_lit),
2431                                        |root: &mut #name| Some(&mut root.#idx_lit),
2432                                    )
2433                                }
2434                            });
2435                        }
2436                        (WrapperKind::OptionAtomic, Some(inner_ty)) => {
2437                            tokens.extend(quote! {
2438                                #[inline(always)]
2439                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2440                                    rust_key_paths::Kp::new(
2441                                        |root: &#name| root.#idx_lit.as_ref(),
2442                                        |root: &mut #name| root.#idx_lit.as_mut(),
2443                                    )
2444                                }
2445                            });
2446                        }
2447                        (WrapperKind::String, None) => {
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                            });
2457                        }
2458                        (WrapperKind::OptionString, None) => {
2459                            tokens.extend(quote! {
2460                                #[inline(always)]
2461                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, std::string::String> {
2462                                    rust_key_paths::Kp::new(
2463                                        |root: &#name| root.#idx_lit.as_ref(),
2464                                        |root: &mut #name| root.#idx_lit.as_mut(),
2465                                    )
2466                                }
2467                            });
2468                        }
2469                        (WrapperKind::OnceCell, Some(inner_ty)) => {
2470                            tokens.extend(quote! {
2471                                #[inline(always)]
2472                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2473                                    rust_key_paths::Kp::new(
2474                                        |root: &#name| root.#idx_lit.get(),
2475                                        |_root: &mut #name| None,
2476                                    )
2477                                }
2478                            });
2479                        }
2480                        (WrapperKind::Lazy, Some(inner_ty)) => {
2481                            tokens.extend(quote! {
2482                                #[inline(always)]
2483                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2484                                    rust_key_paths::Kp::new(
2485                                        |root: &#name| Some(root.#idx_lit.get()),
2486                                        |_root: &mut #name| None,
2487                                    )
2488                                }
2489                            });
2490                        }
2491                        (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
2492                            tokens.extend(quote! {
2493                                #[inline(always)]
2494                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2495                                    rust_key_paths::Kp::new(
2496                                        |root: &#name| root.#idx_lit.as_ref().and_then(|c| c.get()),
2497                                        |_root: &mut #name| None,
2498                                    )
2499                                }
2500                            });
2501                        }
2502                        (WrapperKind::OptionLazy, Some(inner_ty)) => {
2503                            tokens.extend(quote! {
2504                                #[inline(always)]
2505                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2506                                    rust_key_paths::Kp::new(
2507                                        |root: &#name| root.#idx_lit.as_ref().map(|c| c.get()),
2508                                        |_root: &mut #name| None,
2509                                    )
2510                                }
2511                            });
2512                        }
2513                        (WrapperKind::Cell, Some(_inner_ty)) | (WrapperKind::RefCell, Some(_inner_ty))
2514                        | (WrapperKind::PhantomData, Some(_inner_ty)) | (WrapperKind::Range, Some(_inner_ty))
2515                        | (WrapperKind::OptionCell, Some(_inner_ty)) | (WrapperKind::OptionRefCell, Some(_inner_ty))
2516                        | (WrapperKind::OptionPhantomData, Some(_inner_ty)) | (WrapperKind::OptionRange, Some(_inner_ty)) => {
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::Reference, Some(_inner_ty)) => {
2528                            tokens.extend(quote! {
2529                                #[inline(always)]
2530                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2531                                    rust_key_paths::Kp::new(
2532                                        |root: &#name| Some(&root.#idx_lit),
2533                                        |_root: &mut #name| None,
2534                                    )
2535                                }
2536                            });
2537                        }
2538                        (WrapperKind::None, None) => {
2539                            tokens.extend(quote! {
2540                                #[inline(always)]
2541                                pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2542                                    rust_key_paths::Kp::new(
2543                                        |root: &#name| Some(&root.#idx_lit),
2544                                        |root: &mut #name| Some(&mut root.#idx_lit),
2545                                    )
2546                                }
2547                            });
2548                        }
2549                        _ => {
2550                            tokens.extend(quote! {
2551                                #[inline(always)]
2552                                    pub fn #kp_fn() -> rust_key_paths::KpType<'static, #name, #ty> {
2553                                    rust_key_paths::Kp::new(
2554                                        |root: &#name| Some(&root.#idx_lit),
2555                                        |root: &mut #name| Some(&mut root.#idx_lit),
2556                                    )
2557                                }
2558                            });
2559                        }
2560                    }
2561                }
2562
2563                tokens
2564            }
2565            Fields::Unit => {
2566                return syn::Error::new(input_span, "Kp derive does not support unit structs")
2567                .to_compile_error()
2568                .into();
2569            }
2570        },
2571        Data::Enum(data_enum) => {
2572            let mut tokens = proc_macro2::TokenStream::new();
2573
2574            // Generate identity methods for the enum
2575            tokens.extend(quote! {
2576                /// Returns a generic identity keypath for this type
2577                #[inline(always)]
2578                pub fn identity_typed<Root, MutRoot>() -> rust_key_paths::Kp<
2579                    #name,
2580                    #name,
2581                    Root,
2582                    Root,
2583                    MutRoot,
2584                    MutRoot,
2585                    fn(Root) -> Option<Root>,
2586                    fn(MutRoot) -> Option<MutRoot>,
2587                >
2588                where
2589                    Root: std::borrow::Borrow<#name>,
2590                    MutRoot: std::borrow::BorrowMut<#name>,
2591                {
2592                    rust_key_paths::Kp::new(
2593                        |r: Root| Some(r),
2594                        |r: MutRoot| Some(r)
2595                    )
2596                }
2597
2598                /// Returns a simple identity keypath for this type
2599                #[inline(always)]
2600                pub fn identity() -> rust_key_paths::KpType<'static, #name, #name> {
2601                    rust_key_paths::Kp::new(
2602                        |r: &#name| Some(r),
2603                        |r: &mut #name| Some(r)
2604                    )
2605                }
2606            });
2607
2608            for variant in data_enum.variants.iter() {
2609                let v_ident = &variant.ident;
2610                let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
2611
2612                match &variant.fields {
2613                    Fields::Unit => {
2614                        // Unit variant - return keypath that checks if enum matches variant
2615                        tokens.extend(quote! {
2616                            #[inline(always)]
2617                            pub fn #snake() -> rust_key_paths::KpType<'static, #name, ()> {
2618                                rust_key_paths::Kp::new(
2619                                    |root: &#name| match root {
2620                                        #name::#v_ident => {
2621                                            static UNIT: () = ();
2622                                            Some(&UNIT)
2623                                        },
2624                                        _ => None,
2625                                    },
2626                                    |_root: &mut #name| None, // Can't mutate unit variant
2627                                )
2628                            }
2629                        });
2630                    }
2631                    Fields::Unnamed(unnamed) => {
2632                        if unnamed.unnamed.len() == 1 {
2633                            // Single-field tuple variant
2634                            let field_ty = &unnamed.unnamed[0].ty;
2635                            let (kind, inner_ty) = extract_wrapper_inner_type(field_ty);
2636
2637                            match (kind, inner_ty.clone()) {
2638                                (WrapperKind::Option, Some(inner_ty)) => {
2639                                    tokens.extend(quote! {
2640                                        #[inline(always)]
2641                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2642                                            rust_key_paths::Kp::new(
2643                                                |root: &#name| match root {
2644                                                    #name::#v_ident(inner) => inner.as_ref(),
2645                                                    _ => None,
2646                                                },
2647                                                |root: &mut #name| match root {
2648                                                    #name::#v_ident(inner) => inner.as_mut(),
2649                                                    _ => None,
2650                                                },
2651                                            )
2652                                        }
2653                                    });
2654                                }
2655                                (WrapperKind::OptionVecDeque, Some(_inner_ty))
2656                                | (WrapperKind::OptionLinkedList, Some(_inner_ty))
2657                                | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
2658                                | (WrapperKind::OptionHashSet, Some(_inner_ty))
2659                                | (WrapperKind::OptionBTreeSet, Some(_inner_ty))
2660                                | (WrapperKind::OptionResult, Some(_inner_ty))
2661                                | (WrapperKind::OptionBTreeMap, Some(_inner_ty)) => {
2662                                    tokens.extend(quote! {
2663                                        #[inline(always)]
2664                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2665                                            rust_key_paths::Kp::new(
2666                                                |root: &#name| match root {
2667                                                    #name::#v_ident(inner) => Some(inner),
2668                                                    _ => None,
2669                                                },
2670                                                |root: &mut #name| match root {
2671                                                    #name::#v_ident(inner) => Some(inner),
2672                                                    _ => None,
2673                                                },
2674                                            )
2675                                        }
2676                                    });
2677                                }
2678                                (WrapperKind::Vec, Some(inner_ty)) => {
2679                                    tokens.extend(quote! {
2680                                        #[inline(always)]
2681                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2682                                            rust_key_paths::Kp::new(
2683                                                |root: &#name| match root {
2684                                                    #name::#v_ident(inner) => inner.first(),
2685                                                    _ => None,
2686                                                },
2687                                                |root: &mut #name| match root {
2688                                                    #name::#v_ident(inner) => inner.first_mut(),
2689                                                    _ => None,
2690                                                },
2691                                            )
2692                                        }
2693                                    });
2694                                }
2695                                (WrapperKind::Box, Some(inner_ty)) => {
2696                                    // Box in enum: deref to inner (&T / &mut T)
2697                                    tokens.extend(quote! {
2698                                        #[inline(always)]
2699                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2700                                            rust_key_paths::Kp::new(
2701                                                |root: &#name| match root {
2702                                                    #name::#v_ident(inner) => Some(&**inner),
2703                                                    _ => None,
2704                                                },
2705                                                |root: &mut #name| match root {
2706                                                    #name::#v_ident(inner) => Some(&mut **inner),
2707                                                    _ => None,
2708                                                },
2709                                            )
2710                                        }
2711                                    });
2712                                }
2713                                (WrapperKind::Pin, Some(inner_ty)) => {
2714                                    let snake_inner = format_ident!("{}_inner", snake);
2715                                    tokens.extend(quote! {
2716                                        #[inline(always)]
2717                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2718                                            rust_key_paths::Kp::new(
2719                                                |root: &#name| match root {
2720                                                    #name::#v_ident(inner) => Some(inner),
2721                                                    _ => None,
2722                                                },
2723                                                |root: &mut #name| match root {
2724                                                    #name::#v_ident(inner) => Some(inner),
2725                                                    _ => None,
2726                                                },
2727                                            )
2728                                        }
2729                                        #[inline(always)]
2730                                        pub fn #snake_inner() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2731                                        where #inner_ty: std::marker::Unpin
2732                                        {
2733                                            rust_key_paths::Kp::new(
2734                                                |root: &#name| match root {
2735                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_ref(inner).get_ref()),
2736                                                    _ => None,
2737                                                },
2738                                                |root: &mut #name| match root {
2739                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_mut(inner).get_mut()),
2740                                                    _ => None,
2741                                                },
2742                                            )
2743                                        }
2744                                    });
2745                                }
2746                                (WrapperKind::PinBox, Some(inner_ty)) => {
2747                                    let snake_inner = format_ident!("{}_inner", snake);
2748                                    tokens.extend(quote! {
2749                                        #[inline(always)]
2750                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2751                                            rust_key_paths::Kp::new(
2752                                                |root: &#name| match root {
2753                                                    #name::#v_ident(inner) => Some(inner),
2754                                                    _ => None,
2755                                                },
2756                                                |root: &mut #name| match root {
2757                                                    #name::#v_ident(inner) => Some(inner),
2758                                                    _ => None,
2759                                                },
2760                                            )
2761                                        }
2762                                        #[inline(always)]
2763                                        pub fn #snake_inner() -> rust_key_paths::KpType<'static, #name, #inner_ty>
2764                                        where #inner_ty: std::marker::Unpin
2765                                        {
2766                                            rust_key_paths::Kp::new(
2767                                                |root: &#name| match root {
2768                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_ref(inner).get_ref()),
2769                                                    _ => None,
2770                                                },
2771                                                |root: &mut #name| match root {
2772                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_mut(inner).get_mut()),
2773                                                    _ => None,
2774                                                },
2775                                            )
2776                                        }
2777                                    });
2778                                }
2779                                (WrapperKind::Rc, Some(inner_ty)) => {
2780                                    tokens.extend(quote! {
2781                                        #[inline(always)]
2782                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2783                                            rust_key_paths::Kp::new(
2784                                                |root: &#name| match root {
2785                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
2786                                                    _ => None,
2787                                                },
2788                                                |root: &mut #name| match root {
2789                                                    #name::#v_ident(inner) => std::rc::Rc::get_mut(inner),
2790                                                    _ => None,
2791                                                },
2792                                            )
2793                                        }
2794                                    });
2795                                }
2796                                (WrapperKind::Arc, Some(inner_ty)) => {
2797                                    tokens.extend(quote! {
2798                                        #[inline(always)]
2799                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
2800                                            rust_key_paths::Kp::new(
2801                                                |root: &#name| match root {
2802                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
2803                                                    _ => None,
2804                                                },
2805                                                |root: &mut #name| match root {
2806                                                    #name::#v_ident(inner) => std::sync::Arc::get_mut(inner),
2807                                                    _ => None,
2808                                                },
2809                                            )
2810                                        }
2811                                    });
2812                                }
2813                                (WrapperKind::StdArcRwLock, Some(inner_ty)) => {
2814                                    let snake_lock = format_ident!("{}_lock", snake);
2815                                    tokens.extend(quote! {
2816                                        #[inline(always)]
2817                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2818                                            rust_key_paths::Kp::new(
2819                                                |root: &#name| match root {
2820                                                    #name::#v_ident(inner) => Some(inner),
2821                                                    _ => None,
2822                                                },
2823                                                |root: &mut #name| match root {
2824                                                    #name::#v_ident(inner) => Some(inner),
2825                                                    _ => None,
2826                                                },
2827                                            )
2828                                        }
2829                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, #field_ty, #inner_ty> {
2830                                            rust_key_paths::lock::LockKp::new(
2831                                                rust_key_paths::Kp::new(
2832                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2833                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2834                                                ),
2835                                                rust_key_paths::lock::ArcRwLockAccess::new(),
2836                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2837                                            )
2838                                        }
2839                                    });
2840                                }
2841                                (WrapperKind::StdArcMutex, Some(inner_ty)) => {
2842                                    let snake_lock = format_ident!("{}_lock", snake);
2843                                    tokens.extend(quote! {
2844                                        #[inline(always)]
2845                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2846                                            rust_key_paths::Kp::new(
2847                                                |root: &#name| match root {
2848                                                    #name::#v_ident(inner) => Some(inner),
2849                                                    _ => None,
2850                                                },
2851                                                |root: &mut #name| match root {
2852                                                    #name::#v_ident(inner) => Some(inner),
2853                                                    _ => None,
2854                                                },
2855                                            )
2856                                        }
2857                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexFor<#name, #field_ty, #inner_ty> {
2858                                            rust_key_paths::lock::LockKp::new(
2859                                                rust_key_paths::Kp::new(
2860                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2861                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2862                                                ),
2863                                                rust_key_paths::lock::ArcMutexAccess::new(),
2864                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2865                                            )
2866                                        }
2867                                    });
2868                                }
2869                                (WrapperKind::ArcRwLock, Some(inner_ty)) => {
2870                                    let snake_lock = format_ident!("{}_lock", snake);
2871                                    tokens.extend(quote! {
2872                                        #[inline(always)]
2873                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2874                                            rust_key_paths::Kp::new(
2875                                                |root: &#name| match root {
2876                                                    #name::#v_ident(inner) => Some(inner),
2877                                                    _ => None,
2878                                                },
2879                                                |root: &mut #name| match root {
2880                                                    #name::#v_ident(inner) => Some(inner),
2881                                                    _ => None,
2882                                                },
2883                                            )
2884                                        }
2885                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, #field_ty, #inner_ty> {
2886                                            rust_key_paths::lock::LockKp::new(
2887                                                rust_key_paths::Kp::new(
2888                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2889                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2890                                                ),
2891                                                rust_key_paths::lock::ParkingLotRwLockAccess::new(),
2892                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2893                                            )
2894                                        }
2895                                    });
2896                                }
2897                                (WrapperKind::ArcMutex, Some(inner_ty)) => {
2898                                    let snake_lock = format_ident!("{}_lock", snake);
2899                                    tokens.extend(quote! {
2900                                        #[inline(always)]
2901                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2902                                            rust_key_paths::Kp::new(
2903                                                |root: &#name| match root {
2904                                                    #name::#v_ident(inner) => Some(inner),
2905                                                    _ => None,
2906                                                },
2907                                                |root: &mut #name| match root {
2908                                                    #name::#v_ident(inner) => Some(inner),
2909                                                    _ => None,
2910                                                },
2911                                            )
2912                                        }
2913                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, #field_ty, #inner_ty> {
2914                                            rust_key_paths::lock::LockKp::new(
2915                                                rust_key_paths::Kp::new(
2916                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2917                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2918                                                ),
2919                                                rust_key_paths::lock::ParkingLotMutexAccess::new(),
2920                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2921                                            )
2922                                        }
2923                                    });
2924                                }
2925                                (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
2926                                    let snake_async = format_ident!("{}_async", snake);
2927                                    tokens.extend(quote! {
2928                                        #[inline(always)]
2929                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2930                                            rust_key_paths::Kp::new(
2931                                                |root: &#name| match root {
2932                                                    #name::#v_ident(inner) => Some(inner),
2933                                                    _ => None,
2934                                                },
2935                                                |root: &mut #name| match root {
2936                                                    #name::#v_ident(inner) => Some(inner),
2937                                                    _ => None,
2938                                                },
2939                                            )
2940                                        }
2941                                        pub fn #snake_async() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #field_ty, #inner_ty> {
2942                                            rust_key_paths::async_lock::AsyncLockKp::new(
2943                                                rust_key_paths::Kp::new(
2944                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2945                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2946                                                ),
2947                                                rust_key_paths::async_lock::TokioMutexAccess::new(),
2948                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2949                                            )
2950                                        }
2951                                    });
2952                                }
2953                                (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
2954                                    let snake_async = format_ident!("{}_async", snake);
2955                                    tokens.extend(quote! {
2956                                        #[inline(always)]
2957                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2958                                            rust_key_paths::Kp::new(
2959                                                |root: &#name| match root {
2960                                                    #name::#v_ident(inner) => Some(inner),
2961                                                    _ => None,
2962                                                },
2963                                                |root: &mut #name| match root {
2964                                                    #name::#v_ident(inner) => Some(inner),
2965                                                    _ => None,
2966                                                },
2967                                            )
2968                                        }
2969                                        pub fn #snake_async() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #field_ty, #inner_ty> {
2970                                            rust_key_paths::async_lock::AsyncLockKp::new(
2971                                                rust_key_paths::Kp::new(
2972                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2973                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
2974                                                ),
2975                                                rust_key_paths::async_lock::TokioRwLockAccess::new(),
2976                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
2977                                            )
2978                                        }
2979                                    });
2980                                }
2981                                (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
2982                                    let snake_async = format_ident!("{}_async", snake);
2983                                    tokens.extend(quote! {
2984                                        #[inline(always)]
2985                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
2986                                            rust_key_paths::Kp::new(
2987                                                |root: &#name| match root {
2988                                                    #name::#v_ident(inner) => Some(inner),
2989                                                    _ => None,
2990                                                },
2991                                                |root: &mut #name| match root {
2992                                                    #name::#v_ident(inner) => Some(inner),
2993                                                    _ => None,
2994                                                },
2995                                            )
2996                                        }
2997                                        pub fn #snake_async() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
2998                                            rust_key_paths::async_lock::AsyncLockKp::new(
2999                                                rust_key_paths::Kp::new(
3000                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3001                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3002                                                ),
3003                                                rust_key_paths::async_lock::TokioMutexAccess::new(),
3004                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3005                                            )
3006                                        }
3007                                    });
3008                                }
3009                                (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
3010                                    let snake_async = format_ident!("{}_async", snake);
3011                                    tokens.extend(quote! {
3012                                        #[inline(always)]
3013                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3014                                            rust_key_paths::Kp::new(
3015                                                |root: &#name| match root {
3016                                                    #name::#v_ident(inner) => Some(inner),
3017                                                    _ => None,
3018                                                },
3019                                                |root: &mut #name| match root {
3020                                                    #name::#v_ident(inner) => Some(inner),
3021                                                    _ => None,
3022                                                },
3023                                            )
3024                                        }
3025                                        pub fn #snake_async() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
3026                                            rust_key_paths::async_lock::AsyncLockKp::new(
3027                                                rust_key_paths::Kp::new(
3028                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3029                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3030                                                ),
3031                                                rust_key_paths::async_lock::TokioRwLockAccess::new(),
3032                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3033                                            )
3034                                        }
3035                                    });
3036                                }
3037                                (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
3038                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3039                                    let snake_lock = format_ident!("{}_lock", snake);
3040                                    tokens.extend(quote! {
3041                                        #[inline(always)]
3042                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3043                                            rust_key_paths::Kp::new(
3044                                                |root: &#name| match root {
3045                                                    #name::#v_ident(inner) => Some(inner),
3046                                                    _ => None,
3047                                                },
3048                                                |root: &mut #name| match root {
3049                                                    #name::#v_ident(inner) => Some(inner),
3050                                                    _ => None,
3051                                                },
3052                                            )
3053                                        }
3054                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::Mutex<#inner_ty>>> {
3055                                            rust_key_paths::Kp::new(
3056                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3057                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3058                                            )
3059                                        }
3060                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexFor<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, #inner_ty> {
3061                                            rust_key_paths::lock::LockKp::new(
3062                                                rust_key_paths::Kp::new(
3063                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3064                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3065                                                ),
3066                                                rust_key_paths::lock::ArcMutexAccess::new(),
3067                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3068                                            )
3069                                        }
3070                                    });
3071                                }
3072                                (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
3073                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3074                                    let snake_lock = format_ident!("{}_lock", snake);
3075                                    tokens.extend(quote! {
3076                                        #[inline(always)]
3077                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3078                                            rust_key_paths::Kp::new(
3079                                                |root: &#name| match root {
3080                                                    #name::#v_ident(inner) => Some(inner),
3081                                                    _ => None,
3082                                                },
3083                                                |root: &mut #name| match root {
3084                                                    #name::#v_ident(inner) => Some(inner),
3085                                                    _ => None,
3086                                                },
3087                                            )
3088                                        }
3089                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>> {
3090                                            rust_key_paths::Kp::new(
3091                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3092                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3093                                            )
3094                                        }
3095                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, #inner_ty> {
3096                                            rust_key_paths::lock::LockKp::new(
3097                                                rust_key_paths::Kp::new(
3098                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3099                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3100                                                ),
3101                                                rust_key_paths::lock::ParkingLotMutexAccess::new(),
3102                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3103                                            )
3104                                        }
3105                                    });
3106                                }
3107                                (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
3108                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3109                                    let snake_lock = format_ident!("{}_lock", snake);
3110                                    tokens.extend(quote! {
3111                                        #[inline(always)]
3112                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3113                                            rust_key_paths::Kp::new(
3114                                                |root: &#name| match root {
3115                                                    #name::#v_ident(inner) => Some(inner),
3116                                                    _ => None,
3117                                                },
3118                                                |root: &mut #name| match root {
3119                                                    #name::#v_ident(inner) => Some(inner),
3120                                                    _ => None,
3121                                                },
3122                                            )
3123                                        }
3124                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<std::sync::RwLock<#inner_ty>>> {
3125                                            rust_key_paths::Kp::new(
3126                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3127                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3128                                            )
3129                                        }
3130                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, #inner_ty> {
3131                                            rust_key_paths::lock::LockKp::new(
3132                                                rust_key_paths::Kp::new(
3133                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3134                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3135                                                ),
3136                                                rust_key_paths::lock::ArcRwLockAccess::new(),
3137                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3138                                            )
3139                                        }
3140                                    });
3141                                }
3142                                (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
3143                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
3144                                    let snake_lock = format_ident!("{}_lock", snake);
3145                                    tokens.extend(quote! {
3146                                        #[inline(always)]
3147                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3148                                            rust_key_paths::Kp::new(
3149                                                |root: &#name| match root {
3150                                                    #name::#v_ident(inner) => Some(inner),
3151                                                    _ => None,
3152                                                },
3153                                                |root: &mut #name| match root {
3154                                                    #name::#v_ident(inner) => Some(inner),
3155                                                    _ => None,
3156                                                },
3157                                            )
3158                                        }
3159                                        pub fn #snake_unlocked() -> rust_key_paths::KpType<'static, #name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>> {
3160                                            rust_key_paths::Kp::new(
3161                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3162                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3163                                            )
3164                                        }
3165                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, #inner_ty> {
3166                                            rust_key_paths::lock::LockKp::new(
3167                                                rust_key_paths::Kp::new(
3168                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3169                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3170                                                ),
3171                                                rust_key_paths::lock::ParkingLotRwLockAccess::new(),
3172                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
3173                                            )
3174                                        }
3175                                    });
3176                                }
3177                                (WrapperKind::StdMutex, Some(_inner_ty))
3178                                | (WrapperKind::Mutex, Some(_inner_ty))
3179                                | (WrapperKind::StdRwLock, Some(_inner_ty))
3180                                | (WrapperKind::RwLock, Some(_inner_ty)) => {
3181                                    tokens.extend(quote! {
3182                                        #[inline(always)]
3183                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3184                                            rust_key_paths::Kp::new(
3185                                                |root: &#name| match root {
3186                                                    #name::#v_ident(inner) => Some(inner),
3187                                                    _ => None,
3188                                                },
3189                                                |root: &mut #name| match root {
3190                                                    #name::#v_ident(inner) => Some(inner),
3191                                                    _ => None,
3192                                                },
3193                                            )
3194                                        }
3195                                    });
3196                                }
3197                                (WrapperKind::Tagged, Some(inner_ty)) => {
3198                                    tokens.extend(quote! {
3199                                        #[inline(always)]
3200                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3201                                            rust_key_paths::Kp::new(
3202                                                |root: &#name| match root {
3203                                                    #name::#v_ident(inner) => Some(std::ops::Deref::deref(inner)),
3204                                                    _ => None,
3205                                                },
3206                                                |root: &mut #name| match root {
3207                                                    #name::#v_ident(inner) => Some(std::ops::DerefMut::deref_mut(inner)),
3208                                                    _ => None,
3209                                                },
3210                                            )
3211                                        }
3212                                    });
3213                                }
3214                                (WrapperKind::Atomic, None | Some(_)) => {
3215                                    tokens.extend(quote! {
3216                                        #[inline(always)]
3217                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3218                                            rust_key_paths::Kp::new(
3219                                                |root: &#name| match root {
3220                                                    #name::#v_ident(inner) => Some(inner),
3221                                                    _ => None,
3222                                                },
3223                                                |root: &mut #name| match root {
3224                                                    #name::#v_ident(inner) => Some(inner),
3225                                                    _ => None,
3226                                                },
3227                                            )
3228                                        }
3229                                    });
3230                                }
3231                                (WrapperKind::OptionAtomic, Some(inner_ty)) => {
3232                                    tokens.extend(quote! {
3233                                        #[inline(always)]
3234                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3235                                            rust_key_paths::Kp::new(
3236                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
3237                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
3238                                            )
3239                                        }
3240                                    });
3241                                }
3242                                (WrapperKind::Reference, Some(_inner_ty)) => {
3243                                    tokens.extend(quote! {
3244                                        #[inline(always)]
3245                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3246                                            rust_key_paths::Kp::new(
3247                                                |root: &#name| match root {
3248                                                    #name::#v_ident(inner) => Some(inner),
3249                                                    _ => None,
3250                                                },
3251                                                |_root: &mut #name| None,
3252                                            )
3253                                        }
3254                                    });
3255                                }
3256                                (WrapperKind::Weak, Some(_inner_ty)) => {
3257                                    tokens.extend(quote! {
3258                                        #[inline(always)]
3259                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3260                                            rust_key_paths::Kp::new(
3261                                                |root: &#name| match root {
3262                                                    #name::#v_ident(inner) => Some(inner),
3263                                                    _ => None,
3264                                                },
3265                                                |_root: &mut #name| None,
3266                                            )
3267                                        }
3268                                    });
3269                                }
3270                                (WrapperKind::Cow, Some(inner_ty)) => {
3271                                    tokens.extend(quote! {
3272                                        #[inline(always)]
3273                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3274                                            rust_key_paths::Kp::new(
3275                                                |root: &#name| match root {
3276                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
3277                                                    _ => None,
3278                                                },
3279                                                |root: &mut #name| match root {
3280                                                    #name::#v_ident(inner) => Some(inner.to_mut()),
3281                                                    _ => None,
3282                                                },
3283                                            )
3284                                        }
3285                                    });
3286                                }
3287                                (WrapperKind::OptionBox, Some(inner_ty)) => {
3288                                    tokens.extend(quote! {
3289                                        #[inline(always)]
3290                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3291                                            rust_key_paths::Kp::new(
3292                                                |root: &#name| match root {
3293                                                    #name::#v_ident(inner) => inner.as_deref(),
3294                                                    _ => None,
3295                                                },
3296                                                |root: &mut #name| match root {
3297                                                    #name::#v_ident(inner) => inner.as_deref_mut(),
3298                                                    _ => None,
3299                                                },
3300                                            )
3301                                        }
3302                                    });
3303                                }
3304                                (WrapperKind::OptionRc, Some(inner_ty)) => {
3305                                    tokens.extend(quote! {
3306                                        #[inline(always)]
3307                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3308                                            rust_key_paths::Kp::new(
3309                                                |root: &#name| match root {
3310                                                    #name::#v_ident(inner) => inner.as_deref(),
3311                                                    _ => None,
3312                                                },
3313                                                |root: &mut #name| match root {
3314                                                    #name::#v_ident(inner) => inner.as_mut().and_then(std::rc::Rc::get_mut),
3315                                                    _ => None,
3316                                                },
3317                                            )
3318                                        }
3319                                    });
3320                                }
3321                                (WrapperKind::OptionArc, Some(inner_ty)) => {
3322                                    tokens.extend(quote! {
3323                                        #[inline(always)]
3324                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3325                                            rust_key_paths::Kp::new(
3326                                                |root: &#name| match root {
3327                                                    #name::#v_ident(inner) => inner.as_deref(),
3328                                                    _ => None,
3329                                                },
3330                                                |root: &mut #name| match root {
3331                                                    #name::#v_ident(inner) => inner.as_mut().and_then(std::sync::Arc::get_mut),
3332                                                    _ => None,
3333                                                },
3334                                            )
3335                                        }
3336                                    });
3337                                }
3338                                (WrapperKind::OptionCow, Some(inner_ty)) => {
3339                                    tokens.extend(quote! {
3340                                        #[inline(always)]
3341                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3342                                            rust_key_paths::Kp::new(
3343                                                |root: &#name| match root {
3344                                                    #name::#v_ident(inner) => inner.as_ref().map(|c| c.as_ref()),
3345                                                    _ => None,
3346                                                },
3347                                                |root: &mut #name| match root {
3348                                                    #name::#v_ident(inner) => inner.as_mut().map(|c| c.to_mut()),
3349                                                    _ => None,
3350                                                },
3351                                            )
3352                                        }
3353                                    });
3354                                }
3355                                (WrapperKind::OptionTagged, Some(inner_ty)) => {
3356                                    tokens.extend(quote! {
3357                                        #[inline(always)]
3358                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3359                                            rust_key_paths::Kp::new(
3360                                                |root: &#name| match root {
3361                                                    #name::#v_ident(inner) => inner.as_ref().map(|t| std::ops::Deref::deref(t)),
3362                                                    _ => None,
3363                                                },
3364                                                |root: &mut #name| match root {
3365                                                    #name::#v_ident(inner) => inner.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
3366                                                    _ => None,
3367                                                },
3368                                            )
3369                                        }
3370                                    });
3371                                }
3372                                (WrapperKind::OptionReference, Some(inner_ty)) => {
3373                                    tokens.extend(quote! {
3374                                        #[inline(always)]
3375                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3376                                            rust_key_paths::Kp::new(
3377                                                |root: &#name| match root {
3378                                                    #name::#v_ident(inner) => inner.as_ref(),
3379                                                    _ => None,
3380                                                },
3381                                                |_root: &mut #name| None,
3382                                            )
3383                                        }
3384                                    });
3385                                }
3386                                (WrapperKind::String, None) => {
3387                                    tokens.extend(quote! {
3388                                        #[inline(always)]
3389                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3390                                            rust_key_paths::Kp::new(
3391                                                |root: &#name| match root {
3392                                                    #name::#v_ident(inner) => Some(inner),
3393                                                    _ => None,
3394                                                },
3395                                                |root: &mut #name| match root {
3396                                                    #name::#v_ident(inner) => Some(inner),
3397                                                    _ => None,
3398                                                },
3399                                            )
3400                                        }
3401                                    });
3402                                }
3403                                (WrapperKind::OptionString, None) => {
3404                                    tokens.extend(quote! {
3405                                        #[inline(always)]
3406                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, std::string::String> {
3407                                            rust_key_paths::Kp::new(
3408                                                |root: &#name| match root {
3409                                                    #name::#v_ident(inner) => inner.as_ref(),
3410                                                    _ => None,
3411                                                },
3412                                                |root: &mut #name| match root {
3413                                                    #name::#v_ident(inner) => inner.as_mut(),
3414                                                    _ => None,
3415                                                },
3416                                            )
3417                                        }
3418                                    });
3419                                }
3420                                (WrapperKind::OnceCell, Some(inner_ty)) => {
3421                                    tokens.extend(quote! {
3422                                        #[inline(always)]
3423                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3424                                            rust_key_paths::Kp::new(
3425                                                |root: &#name| match root {
3426                                                    #name::#v_ident(inner) => inner.get(),
3427                                                    _ => None,
3428                                                },
3429                                                |_root: &mut #name| None,
3430                                            )
3431                                        }
3432                                    });
3433                                }
3434                                (WrapperKind::Lazy, Some(inner_ty)) => {
3435                                    tokens.extend(quote! {
3436                                        #[inline(always)]
3437                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3438                                            rust_key_paths::Kp::new(
3439                                                |root: &#name| match root {
3440                                                    #name::#v_ident(inner) => Some(inner.get()),
3441                                                    _ => None,
3442                                                },
3443                                                |_root: &mut #name| None,
3444                                            )
3445                                        }
3446                                    });
3447                                }
3448                                (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
3449                                    tokens.extend(quote! {
3450                                        #[inline(always)]
3451                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #inner_ty> {
3452                                            rust_key_paths::Kp::new(
3453                                                |root: &#name| match root {
3454                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|c| c.get()),
3455                                                    _ => None,
3456                                                },
3457                                                |_root: &mut #name| None,
3458                                            )
3459                                        }
3460                                    });
3461                                }
3462                                (WrapperKind::OptionLazy, 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.get()),
3469                                                    _ => None,
3470                                                },
3471                                                |_root: &mut #name| None,
3472                                            )
3473                                        }
3474                                    });
3475                                }
3476                                (WrapperKind::Cell, Some(_inner_ty)) | (WrapperKind::RefCell, Some(_inner_ty))
3477                                | (WrapperKind::PhantomData, Some(_inner_ty)) | (WrapperKind::Range, Some(_inner_ty))
3478                                | (WrapperKind::OptionCell, Some(_inner_ty)) | (WrapperKind::OptionRefCell, Some(_inner_ty))
3479                                | (WrapperKind::OptionPhantomData, Some(_inner_ty)) | (WrapperKind::OptionRange, Some(_inner_ty)) => {
3480                                    tokens.extend(quote! {
3481                                        #[inline(always)]
3482                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3483                                            rust_key_paths::Kp::new(
3484                                                |root: &#name| match root {
3485                                                    #name::#v_ident(inner) => Some(inner),
3486                                                    _ => None,
3487                                                },
3488                                                |root: &mut #name| match root {
3489                                                    #name::#v_ident(inner) => Some(inner),
3490                                                    _ => None,
3491                                                },
3492                                            )
3493                                        }
3494                                    });
3495                                }
3496                                (WrapperKind::None, None) => {
3497                                    // Basic type
3498                                    tokens.extend(quote! {
3499                                        #[inline(always)]
3500                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3501                                            rust_key_paths::Kp::new(
3502                                                |root: &#name| match root {
3503                                                    #name::#v_ident(inner) => Some(inner),
3504                                                    _ => None,
3505                                                },
3506                                                |root: &mut #name| match root {
3507                                                    #name::#v_ident(inner) => Some(inner),
3508                                                    _ => None,
3509                                                },
3510                                            )
3511                                        }
3512                                    });
3513                                }
3514                                _ => {
3515                                    // Other wrapper types - return keypath to field
3516                                    tokens.extend(quote! {
3517                                        #[inline(always)]
3518                                        pub fn #snake() -> rust_key_paths::KpType<'static, #name, #field_ty> {
3519                                            rust_key_paths::Kp::new(
3520                                                |root: &#name| match root {
3521                                                    #name::#v_ident(inner) => Some(inner),
3522                                                    _ => None,
3523                                                },
3524                                                |root: &mut #name| match root {
3525                                                    #name::#v_ident(inner) => Some(inner),
3526                                                    _ => None,
3527                                                },
3528                                            )
3529                                        }
3530                                    });
3531                                }
3532                            }
3533                        } else {
3534                            // Multi-field tuple variant - return keypath to variant itself
3535                            tokens.extend(quote! {
3536                                #[inline(always)]
3537                                pub fn #snake() -> rust_key_paths::KpType<'static, #name, #name> {
3538                                    rust_key_paths::Kp::new(
3539                                        |root: &#name| match root {
3540                                            #name::#v_ident(..) => Some(root),
3541                                            _ => None,
3542                                        },
3543                                        |root: &mut #name| match root {
3544                                            #name::#v_ident(..) => Some(root),
3545                                            _ => None,
3546                                        },
3547                                    )
3548                                }
3549                            });
3550                        }
3551                    }
3552                    Fields::Named(_) => {
3553                        // Named field variant - return keypath to variant itself
3554                        tokens.extend(quote! {
3555                            pub fn #snake() -> rust_key_paths::KpType<'static, #name, #name> {
3556                                rust_key_paths::Kp::new(
3557                                    |root: &#name| match root {
3558                                        #name::#v_ident { .. } => Some(root),
3559                                        _ => None,
3560                                    },
3561                                    |root: &mut #name| match root {
3562                                        #name::#v_ident { .. } => Some(root),
3563                                        _ => None,
3564                                    },
3565                                )
3566                            }
3567                        });
3568                    }
3569                }
3570            }
3571
3572            tokens
3573        }
3574        Data::Union(_) => {
3575            return syn::Error::new(input_span, "Kp derive does not support unions")
3576            .to_compile_error()
3577            .into();
3578        }
3579    };
3580
3581    let expanded = quote! {
3582        impl #name {
3583            #methods
3584        }
3585    };
3586
3587    TokenStream::from(expanded)
3588}
3589
3590/// Derive macro that generates `partial_kps() -> Vec<PKp<Self>>` returning all field/variant keypaths.
3591/// **Requires `#[derive(Kp)]`** so the keypath accessor methods exist.
3592///
3593/// For structs: returns keypaths for each field. For enums: returns keypaths for each variant
3594/// (using the same methods Kp generates, e.g. `some_variant()`).
3595///
3596/// # Example
3597/// ```
3598/// use key_paths_derive::{Kp, Pkp};
3599/// use rust_key_paths::PKp;
3600///
3601/// #[derive(Kp, Pkp)]
3602/// struct Person {
3603///     name: String,
3604///     age: i32,
3605/// }
3606///
3607/// let kps = Person::partial_kps();
3608/// assert_eq!(kps.len(), 2);
3609/// ```
3610#[proc_macro_derive(Pkp)]
3611pub fn derive_partial_keypaths(input: TokenStream) -> TokenStream {
3612    let input = parse_macro_input!(input as DeriveInput);
3613    let name = &input.ident;
3614
3615    let kp_calls = match &input.data {
3616        Data::Struct(data_struct) => match &data_struct.fields {
3617            Fields::Named(fields_named) => {
3618                let calls: Vec<_> = fields_named
3619                    .named
3620                    .iter()
3621                    .filter_map(|f| f.ident.as_ref())
3622                    .map(|field_ident| {
3623                        quote! { rust_key_paths::PKp::new(Self::#field_ident()) }
3624                    })
3625                    .collect();
3626                quote! { #(#calls),* }
3627            }
3628            Fields::Unnamed(unnamed) => {
3629                let calls: Vec<_> = (0..unnamed.unnamed.len())
3630                    .map(|idx| {
3631                        let kp_fn = format_ident!("f{}", idx);
3632                        quote! { rust_key_paths::PKp::new(Self::#kp_fn()) }
3633                    })
3634                    .collect();
3635                quote! { #(#calls),* }
3636            }
3637            Fields::Unit => quote! {},
3638        },
3639        Data::Enum(data_enum) => {
3640            let calls: Vec<_> = data_enum
3641                .variants
3642                .iter()
3643                .map(|variant| {
3644                    let v_ident = &variant.ident;
3645                    let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
3646                    quote! { rust_key_paths::PKp::new(Self::#snake()) }
3647                })
3648                .collect();
3649            quote! { #(#calls),* }
3650        }
3651        Data::Union(_) => {
3652            return syn::Error::new(
3653                input.ident.span(),
3654                "Pkp derive does not support unions",
3655            )
3656            .to_compile_error()
3657            .into();
3658        }
3659    };
3660
3661    let expanded = quote! {
3662        impl #name {
3663            /// Returns a vec of all field keypaths as partial keypaths (type-erased).
3664            #[inline(always)]
3665            pub fn partial_kps() -> Vec<rust_key_paths::PKp<#name>> {
3666                vec![#kp_calls]
3667            }
3668        }
3669    };
3670
3671    TokenStream::from(expanded)
3672}
3673
3674/// Derive macro that generates `any_kps() -> Vec<AKp>` returning all field/variant keypaths as any keypaths.
3675/// **Requires `#[derive(Kp)]`** so the keypath accessor methods exist.
3676/// AKp type-erases both Root and Value, enabling heterogeneous collections of keypaths.
3677///
3678/// For structs: returns keypaths for each field. For enums: returns keypaths for each variant
3679/// (using the same methods Kp generates, e.g. `some_variant()`).
3680///
3681/// # Example
3682/// ```
3683/// use key_paths_derive::{Kp, Akp};
3684/// use rust_key_paths::AKp;
3685///
3686/// #[derive(Kp, Akp)]
3687/// struct Person {
3688///     name: String,
3689///     age: i32,
3690/// }
3691///
3692/// let kps = Person::any_kps();
3693/// assert_eq!(kps.len(), 2);
3694/// let person = Person { name: "Alice".into(), age: 30 };
3695/// let name: Option<&String> = kps[0].get(&person as &dyn std::any::Any).and_then(|v| v.downcast_ref());
3696/// assert_eq!(name, Some(&"Alice".to_string()));
3697/// ```
3698#[proc_macro_derive(Akp)]
3699pub fn derive_any_keypaths(input: TokenStream) -> TokenStream {
3700    let input = parse_macro_input!(input as DeriveInput);
3701    let name = &input.ident;
3702
3703    let kp_calls = match &input.data {
3704        Data::Struct(data_struct) => match &data_struct.fields {
3705            Fields::Named(fields_named) => {
3706                let calls: Vec<_> = fields_named
3707                    .named
3708                    .iter()
3709                    .filter_map(|f| f.ident.as_ref())
3710                    .map(|field_ident| {
3711                        quote! { rust_key_paths::AKp::new(Self::#field_ident()) }
3712                    })
3713                    .collect();
3714                quote! { #(#calls),* }
3715            }
3716            Fields::Unnamed(unnamed) => {
3717                let calls: Vec<_> = (0..unnamed.unnamed.len())
3718                    .map(|idx| {
3719                        let kp_fn = format_ident!("f{}", idx);
3720                        quote! { rust_key_paths::AKp::new(Self::#kp_fn()) }
3721                    })
3722                    .collect();
3723                quote! { #(#calls),* }
3724            }
3725            Fields::Unit => quote! {},
3726        },
3727        Data::Enum(data_enum) => {
3728            let calls: Vec<_> = data_enum
3729                .variants
3730                .iter()
3731                .map(|variant| {
3732                    let v_ident = &variant.ident;
3733                    let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
3734                    quote! { rust_key_paths::AKp::new(Self::#snake()) }
3735                })
3736                .collect();
3737            quote! { #(#calls),* }
3738        }
3739        Data::Union(_) => {
3740            return syn::Error::new(
3741                input.ident.span(),
3742                "Akp derive does not support unions",
3743            )
3744            .to_compile_error()
3745            .into();
3746        }
3747    };
3748
3749    let expanded = quote! {
3750        impl #name {
3751            /// Returns a vec of all field keypaths as any keypaths (fully type-erased).
3752            #[inline(always)]
3753            pub fn any_kps() -> Vec<rust_key_paths::AKp> {
3754                vec![#kp_calls]
3755            }
3756        }
3757    };
3758
3759    TokenStream::from(expanded)
3760}