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    StdArcMutexOption,
72    StdArcRwLockOption,
73    OptionStdArcMutex,
74    OptionStdArcRwLock,
75    // Synchronization primitives default
76    StdMutex,
77    StdRwLock,
78    StdMutexOption,
79    StdRwLockOption,
80    OptionStdMutex,
81    OptionStdRwLock,
82    // Synchronization primitives (parking_lot)
83    Mutex,
84    RwLock,
85    OptionMutex,
86    OptionRwLock,
87    // Synchronization primitives (tokio::sync - requires tokio feature)
88    TokioMutex,
89    TokioRwLock,
90    // parking_lot
91    ArcMutex,
92    ArcRwLock,
93    ArcMutexOption,
94    ArcRwLockOption,
95    OptionArcMutex,
96    OptionArcRwLock,
97    MutexOption,
98    RwLockOption,
99    // Arc with synchronization primitives (tokio::sync - requires tokio feature)
100    TokioArcMutex,
101    TokioArcRwLock,
102    OptionTokioArcMutex,
103    OptionTokioArcRwLock,
104    // Tagged types
105    Tagged,
106    OptionTagged,
107    // Clone-on-write (std::borrow::Cow)
108    Cow,
109    OptionCow,
110    // Reference types (&T, &str, &[T], etc.)
111    Reference,
112    OptionReference,
113    // Atomic types (std::sync::atomic::*)
114    Atomic,
115    OptionAtomic,
116    // Pin types
117    Pin,
118    PinBox,
119    /// Field marked with #[pin] - plain type (pin_project pattern)
120    PinnedField,
121    /// Field marked with #[pin] - Future type (pin_project pattern)
122    PinnedFuture,
123    /// Field marked with #[pin] - Box<dyn Future> (pin_project pattern)
124    PinnedBoxFuture,
125}
126
127/// Helper function to check if a type path is exactly under std::sync (not lock_api or parking_lot).
128/// Requires the path to start with "std" then "sync" so we don't confuse with RwLock&lt;RawRwLock, T&gt; (lock_api).
129fn is_std_sync_type(path: &syn::Path) -> bool {
130    let segments: Vec<_> = path.segments.iter().map(|s| s.ident.to_string()).collect();
131    segments.len() >= 2
132        && segments.get(0).map(|s| s.as_str()) == Some("std")
133        && segments.get(1).map(|s| s.as_str()) == Some("sync")
134}
135
136/// Helper function to check if a type path is exactly under tokio::sync.
137fn is_tokio_sync_type(path: &syn::Path) -> bool {
138    let segments: Vec<_> = path.segments.iter().map(|s| s.ident.to_string()).collect();
139    segments.len() >= 2
140        && segments.get(0).map(|s| s.as_str()) == Some("tokio")
141        && segments.get(1).map(|s| s.as_str()) == Some("sync")
142}
143
144/// Helper function to check if a type path is under parking_lot (RwLock/Mutex from lock_api).
145/// Use so we never treat parking_lot::RwLock as std::sync::RwLock.
146fn is_parking_lot_type(path: &syn::Path) -> bool {
147    path.segments.first().map(|s| s.ident == "parking_lot") == Some(true)
148}
149
150/// Helper function to check if a type path is under std::sync::atomic (strict prefix).
151fn is_std_sync_atomic_type(path: &syn::Path) -> bool {
152    let segments: Vec<_> = path.segments.iter().map(|s| s.ident.to_string()).collect();
153    segments.len() >= 3
154        && segments.get(0).map(|s| s.as_str()) == Some("std")
155        && segments.get(1).map(|s| s.as_str()) == Some("sync")
156        && segments.get(2).map(|s| s.as_str()) == Some("atomic")
157}
158
159/// Atomic type idents (no type params): AtomicBool, AtomicI8, etc.
160const ATOMIC_TYPE_IDENTS: &[&str] = &[
161    "AtomicBool",
162    "AtomicI8",
163    "AtomicI16",
164    "AtomicI32",
165    "AtomicI64",
166    "AtomicI128",
167    "AtomicIsize",
168    "AtomicU8",
169    "AtomicU16",
170    "AtomicU32",
171    "AtomicU64",
172    "AtomicU128",
173    "AtomicUsize",
174];
175
176fn extract_wrapper_inner_type(ty: &Type) -> (WrapperKind, Option<Type>) {
177    use syn::{GenericArgument, PathArguments};
178
179    // Handle reference types: &T, &'a str, &[T], etc.
180    if let Type::Reference(tr) = ty {
181        return (WrapperKind::Reference, Some((*tr.elem).clone()));
182    }
183
184    if let Type::Path(tp) = ty {
185        // Check if this is explicitly a std::sync type
186        let is_std_sync = is_std_sync_type(&tp.path);
187        // Check if this is explicitly a tokio::sync type
188        let is_tokio_sync = is_tokio_sync_type(&tp.path);
189
190        if let Some(seg) = tp.path.segments.last() {
191            let ident_str = seg.ident.to_string();
192
193            if let PathArguments::AngleBracketed(ab) = &seg.arguments {
194                let args: Vec<_> = ab.args.iter().collect();
195
196                // Handle map types (HashMap, BTreeMap) - they have K, V parameters
197                if ident_str == "HashMap" || ident_str == "BTreeMap" {
198                    if let (Some(_key_arg), Some(value_arg)) = (args.get(0), args.get(1)) {
199                        if let GenericArgument::Type(inner) = value_arg {
200                            // Check for nested Option in map values
201                            let (inner_kind, inner_inner) = extract_wrapper_inner_type(inner);
202                            match (ident_str.as_str(), inner_kind) {
203                                ("HashMap", WrapperKind::Option) => {
204                                    return (WrapperKind::HashMapOption, inner_inner);
205                                }
206                                ("BTreeMap", WrapperKind::Option) => {
207                                    return (WrapperKind::BTreeMapOption, inner_inner);
208                                }
209                                _ => {
210                                    return match ident_str.as_str() {
211                                        "HashMap" => (WrapperKind::HashMap, Some(inner.clone())),
212                                        "BTreeMap" => (WrapperKind::BTreeMap, Some(inner.clone())),
213                                        _ => (WrapperKind::None, None),
214                                    };
215                                }
216                            }
217                        }
218                    }
219                }
220                // Handle Cow<'a, B> - has lifetime then type parameter
221                else if ident_str == "Cow" {
222                    if let Some(inner) = args.iter().find_map(|arg| {
223                        if let GenericArgument::Type(t) = arg {
224                            Some(t.clone())
225                        } else {
226                            None
227                        }
228                    }) {
229                        return (WrapperKind::Cow, Some(inner));
230                    }
231                }
232                // Handle single-parameter container types
233                else if let Some(arg) = args.get(0) {
234                    if let GenericArgument::Type(inner) = arg {
235                        // Check for nested containers first
236                        let (inner_kind, inner_inner) = extract_wrapper_inner_type(inner);
237
238                        // Handle nested combinations
239                        match (ident_str.as_str(), inner_kind) {
240                            ("Option", WrapperKind::Box) => {
241                                return (WrapperKind::OptionBox, inner_inner);
242                            }
243                            ("Option", WrapperKind::Rc) => {
244                                return (WrapperKind::OptionRc, inner_inner);
245                            }
246                            ("Option", WrapperKind::Arc) => {
247                                return (WrapperKind::OptionArc, inner_inner);
248                            }
249                            ("Option", WrapperKind::Vec) => {
250                                return (WrapperKind::OptionVec, inner_inner);
251                            }
252                            ("Option", WrapperKind::HashMap) => {
253                                return (WrapperKind::OptionHashMap, inner_inner);
254                            }
255                            ("Option", WrapperKind::BTreeMap) => {
256                                return (WrapperKind::OptionBTreeMap, inner_inner);
257                            }
258                            ("Option", WrapperKind::VecDeque) => {
259                                return (WrapperKind::OptionVecDeque, inner_inner);
260                            }
261                            ("Option", WrapperKind::LinkedList) => {
262                                return (WrapperKind::OptionLinkedList, inner_inner);
263                            }
264                            ("Option", WrapperKind::BinaryHeap) => {
265                                return (WrapperKind::OptionBinaryHeap, inner_inner);
266                            }
267                            ("Option", WrapperKind::HashSet) => {
268                                return (WrapperKind::OptionHashSet, inner_inner);
269                            }
270                            ("Option", WrapperKind::BTreeSet) => {
271                                return (WrapperKind::OptionBTreeSet, inner_inner);
272                            }
273                            ("Option", WrapperKind::Result) => {
274                                return (WrapperKind::OptionResult, inner_inner);
275                            }
276                            ("Option", WrapperKind::StdArcMutex) => {
277                                return (WrapperKind::OptionStdArcMutex, inner_inner);
278                            }
279                            ("Option", WrapperKind::StdArcRwLock) => {
280                                return (WrapperKind::OptionStdArcRwLock, inner_inner);
281                            }
282                            ("Option", WrapperKind::ArcMutex) => {
283                                return (WrapperKind::OptionArcMutex, inner_inner);
284                            }
285                            ("Option", WrapperKind::ArcRwLock) => {
286                                return (WrapperKind::OptionArcRwLock, inner_inner);
287                            }
288                            ("Option", WrapperKind::StdMutex) => {
289                                return (WrapperKind::OptionStdMutex, inner_inner);
290                            }
291                            ("Option", WrapperKind::StdRwLock) => {
292                                return (WrapperKind::OptionStdRwLock, inner_inner);
293                            }
294                            ("Option", WrapperKind::Mutex) => {
295                                return (WrapperKind::OptionMutex, inner_inner);
296                            }
297                            ("Option", WrapperKind::RwLock) => {
298                                return (WrapperKind::OptionRwLock, inner_inner);
299                            }
300                            ("Option", WrapperKind::TokioArcMutex) => {
301                                return (WrapperKind::OptionTokioArcMutex, inner_inner);
302                            }
303                            ("Option", WrapperKind::TokioArcRwLock) => {
304                                return (WrapperKind::OptionTokioArcRwLock, inner_inner);
305                            }
306                            ("Option", WrapperKind::Cow) => {
307                                return (WrapperKind::OptionCow, inner_inner);
308                            }
309                            ("Option", WrapperKind::Tagged) => {
310                                return (WrapperKind::OptionTagged, inner_inner);
311                            }
312                            ("Option", WrapperKind::Reference) => {
313                                return (WrapperKind::OptionReference, Some(inner.clone()));
314                            }
315                            ("Option", WrapperKind::Atomic) => {
316                                return (WrapperKind::OptionAtomic, Some(inner.clone()));
317                            }
318                            ("Option", WrapperKind::String) => {
319                                return (WrapperKind::OptionString, None);
320                            }
321                            ("Option", WrapperKind::Cell) => {
322                                return (WrapperKind::OptionCell, inner_inner);
323                            }
324                            ("Option", WrapperKind::RefCell) => {
325                                return (WrapperKind::OptionRefCell, inner_inner);
326                            }
327                            ("Option", WrapperKind::OnceCell) => {
328                                return (WrapperKind::OptionOnceCell, inner_inner);
329                            }
330                            ("Option", WrapperKind::Lazy) => {
331                                return (WrapperKind::OptionLazy, inner_inner);
332                            }
333                            ("Option", WrapperKind::PhantomData) => {
334                                return (WrapperKind::OptionPhantomData, inner_inner);
335                            }
336                            ("Option", WrapperKind::Range) => {
337                                return (WrapperKind::OptionRange, inner_inner);
338                            }
339                            ("Pin", WrapperKind::Box) => {
340                                return (WrapperKind::PinBox, inner_inner);
341                            }
342                            ("Box", WrapperKind::Option) => {
343                                return (WrapperKind::BoxOption, inner_inner);
344                            }
345                            ("Rc", WrapperKind::Option) => {
346                                return (WrapperKind::RcOption, inner_inner);
347                            }
348                            ("Arc", WrapperKind::Option) => {
349                                return (WrapperKind::ArcOption, inner_inner);
350                            }
351                            ("Vec", WrapperKind::Option) => {
352                                return (WrapperKind::VecOption, inner_inner);
353                            }
354                            ("VecDeque", WrapperKind::Option) => {
355                                return (WrapperKind::VecDequeOption, inner_inner);
356                            }
357                            ("LinkedList", WrapperKind::Option) => {
358                                return (WrapperKind::LinkedListOption, inner_inner);
359                            }
360                            ("BinaryHeap", WrapperKind::Option) => {
361                                return (WrapperKind::BinaryHeapOption, inner_inner);
362                            }
363                            ("HashSet", WrapperKind::Option) => {
364                                return (WrapperKind::HashSetOption, inner_inner);
365                            }
366                            ("BTreeSet", WrapperKind::Option) => {
367                                return (WrapperKind::BTreeSetOption, inner_inner);
368                            }
369                            ("Result", WrapperKind::Option) => {
370                                return (WrapperKind::ResultOption, inner_inner);
371                            }
372                            ("HashMap", WrapperKind::Option) => {
373                                return (WrapperKind::HashMapOption, inner_inner);
374                            }
375                            // BTreeMapOption is handled in the map block (HashMap/BTreeMap)
376                            // Mutex<Option<T>> / RwLock<Option<T>> (yields LockKp value T)
377                            // std::sync::Mutex<Option<T>> / RwLock<Option<T>>
378                            ("Mutex", WrapperKind::Option) if is_std_sync_type(&tp.path) => {
379                                return (WrapperKind::StdMutexOption, inner_inner);
380                            }
381                            ("RwLock", WrapperKind::Option) if is_std_sync_type(&tp.path) => {
382                                return (WrapperKind::StdRwLockOption, inner_inner);
383                            }
384                            // parking_lot::Mutex<Option<T>> / RwLock<Option<T>>, and bare Mutex/RwLock assumed parking_lot
385                            ("Mutex", WrapperKind::Option) => {
386                                return (WrapperKind::MutexOption, inner_inner);
387                            }
388                            ("RwLock", WrapperKind::Option) => {
389                                return (WrapperKind::RwLockOption, inner_inner);
390                            }
391                            // std::sync variants (when inner is StdMutex/StdRwLock)
392                            ("Arc", WrapperKind::StdMutex) => {
393                                return (WrapperKind::StdArcMutex, inner_inner);
394                            }
395                            ("Arc", WrapperKind::StdRwLock) => {
396                                return (WrapperKind::StdArcRwLock, inner_inner);
397                            }
398                            ("Arc", WrapperKind::StdMutexOption) => {
399                                return (WrapperKind::StdArcMutexOption, inner_inner);
400                            }
401                            ("Arc", WrapperKind::StdRwLockOption) => {
402                                return (WrapperKind::StdArcRwLockOption, inner_inner);
403                            }
404                            // parking_lot variants (default - when inner is Mutex/RwLock without std::sync prefix)
405                            ("Arc", WrapperKind::Mutex) => {
406                                return (WrapperKind::ArcMutex, inner_inner);
407                            }
408                            ("Arc", WrapperKind::RwLock) => {
409                                return (WrapperKind::ArcRwLock, inner_inner);
410                            }
411                            ("Arc", WrapperKind::MutexOption) => {
412                                return (WrapperKind::ArcMutexOption, inner_inner);
413                            }
414                            ("Arc", WrapperKind::RwLockOption) => {
415                                return (WrapperKind::ArcRwLockOption, inner_inner);
416                            }
417                            // tokio::sync variants (when inner is TokioMutex/TokioRwLock)
418                            ("Arc", WrapperKind::TokioMutex) => {
419                                return (WrapperKind::TokioArcMutex, inner_inner);
420                            }
421                            ("Arc", WrapperKind::TokioRwLock) => {
422                                return (WrapperKind::TokioArcRwLock, inner_inner);
423                            }
424                            _ => {
425                                // Handle single-level containers
426                                // For Mutex and RwLock:
427                                // - If path contains std::sync, it's std::sync (StdMutex/StdRwLock)
428                                // - Otherwise, default to parking_lot (Mutex/RwLock)
429                                return match ident_str.as_str() {
430                                    "Option" => (WrapperKind::Option, Some(inner.clone())),
431                                    "Box" => (WrapperKind::Box, Some(inner.clone())),
432                                    "Rc" => (WrapperKind::Rc, Some(inner.clone())),
433                                    "Arc" => (WrapperKind::Arc, Some(inner.clone())),
434                                    "Vec" => (WrapperKind::Vec, Some(inner.clone())),
435                                    "HashSet" => (WrapperKind::HashSet, Some(inner.clone())),
436                                    "BTreeSet" => (WrapperKind::BTreeSet, Some(inner.clone())),
437                                    "VecDeque" => (WrapperKind::VecDeque, Some(inner.clone())),
438                                    "LinkedList" => (WrapperKind::LinkedList, Some(inner.clone())),
439                                    "BinaryHeap" => (WrapperKind::BinaryHeap, Some(inner.clone())),
440                                    "Result" => (WrapperKind::Result, Some(inner.clone())),
441                                    // Explicit parking_lot path (lock_api::RwLock) — never treat as std
442                                    "Mutex" if is_parking_lot_type(&tp.path) => {
443                                        (WrapperKind::Mutex, Some(inner.clone()))
444                                    }
445                                    "RwLock" if is_parking_lot_type(&tp.path) => {
446                                        (WrapperKind::RwLock, Some(inner.clone()))
447                                    }
448                                    // std::sync::Mutex and std::sync::RwLock only when path starts with std::sync
449                                    "Mutex" if is_std_sync => {
450                                        (WrapperKind::StdMutex, Some(inner.clone()))
451                                    }
452                                    "RwLock" if is_std_sync => {
453                                        (WrapperKind::StdRwLock, Some(inner.clone()))
454                                    }
455                                    // tokio::sync::Mutex and tokio::sync::RwLock
456                                    "Mutex" if is_tokio_sync => {
457                                        (WrapperKind::TokioMutex, Some(inner.clone()))
458                                    }
459                                    "RwLock" if is_tokio_sync => {
460                                        (WrapperKind::TokioRwLock, Some(inner.clone()))
461                                    }
462                                    // Default: parking_lot (bare Mutex/RwLock or unknown path)
463                                    "Mutex" => (WrapperKind::Mutex, Some(inner.clone())),
464                                    "RwLock" => (WrapperKind::RwLock, Some(inner.clone())),
465                                    "Weak" => (WrapperKind::Weak, Some(inner.clone())),
466                                    "Tagged" => (WrapperKind::Tagged, Some(inner.clone())),
467                                    "Cow" => (WrapperKind::Cow, Some(inner.clone())),
468                                    "AtomicPtr" if is_std_sync_atomic_type(&tp.path) => {
469                                        (WrapperKind::Atomic, None)
470                                    }
471                                    "Pin" => (WrapperKind::Pin, Some(inner.clone())),
472                                    "Cell" => (WrapperKind::Cell, Some(inner.clone())),
473                                    "RefCell" => (WrapperKind::RefCell, Some(inner.clone())),
474                                    "OnceCell" | "OnceLock" => {
475                                        (WrapperKind::OnceCell, Some(inner.clone()))
476                                    }
477                                    "Lazy" | "LazyLock" => (WrapperKind::Lazy, Some(inner.clone())),
478                                    "PhantomData" => {
479                                        (WrapperKind::PhantomData, Some(inner.clone()))
480                                    }
481                                    "Range" | "RangeInclusive" => {
482                                        (WrapperKind::Range, Some(inner.clone()))
483                                    }
484                                    _ => (WrapperKind::None, None),
485                                };
486                            }
487                        }
488                    }
489                }
490            }
491            // Handle atomic types with no angle bracket args (AtomicBool, AtomicI32, etc.)
492            if matches!(seg.arguments, PathArguments::None) {
493                if ident_str == "String" {
494                    return (WrapperKind::String, None);
495                }
496                if is_std_sync_atomic_type(&tp.path)
497                    && ATOMIC_TYPE_IDENTS.contains(&ident_str.as_str())
498                {
499                    return (WrapperKind::Atomic, None);
500                }
501            }
502        }
503    }
504    (WrapperKind::None, None)
505}
506
507/// Check if a field has the #[pin] attribute (pin_project pattern).
508fn field_has_pin_attr(field: &syn::Field) -> bool {
509    field
510        .attrs
511        .iter()
512        .any(|attr| attr.path().get_ident().map(|i| i == "pin").unwrap_or(false))
513}
514
515/// Check if a type is a Future (dyn Future, impl Future, or Box<dyn Future>).
516fn is_future_type(ty: &Type) -> bool {
517    use syn::{GenericArgument, PathArguments, TypeParamBound};
518
519    match ty {
520        Type::TraitObject(trait_obj) => trait_obj.bounds.iter().any(|b| {
521            if let TypeParamBound::Trait(t) = b {
522                t.path
523                    .segments
524                    .last()
525                    .map(|s| s.ident == "Future")
526                    .unwrap_or(false)
527            } else {
528                false
529            }
530        }),
531        Type::ImplTrait(impl_trait) => impl_trait.bounds.iter().any(|b| {
532            if let TypeParamBound::Trait(t) = b {
533                t.path
534                    .segments
535                    .last()
536                    .map(|s| s.ident == "Future")
537                    .unwrap_or(false)
538            } else {
539                false
540            }
541        }),
542        Type::Path(tp) => {
543            if let Some(seg) = tp.path.segments.last() {
544                match seg.ident.to_string().as_str() {
545                    "Box" | "Pin" => {
546                        if let PathArguments::AngleBracketed(args) = &seg.arguments {
547                            if let Some(GenericArgument::Type(inner)) = args.args.first() {
548                                return is_future_type(inner);
549                            }
550                        }
551                    }
552                    _ => {}
553                }
554            }
555            false
556        }
557        _ => false,
558    }
559}
560
561/// Extract Output type from Future trait bound (dyn Future<Output = T>, impl Future<Output = T>, etc.).
562fn extract_future_output(ty: &Type) -> Option<Type> {
563    use syn::{GenericArgument, PathArguments, TypeParamBound};
564
565    let bounds = match ty {
566        Type::TraitObject(t) => &t.bounds,
567        Type::ImplTrait(t) => &t.bounds,
568        Type::Path(tp) => {
569            if let Some(seg) = tp.path.segments.last() {
570                if matches!(seg.ident.to_string().as_str(), "Box" | "Pin") {
571                    if let PathArguments::AngleBracketed(args) = &seg.arguments {
572                        if let Some(GenericArgument::Type(inner)) = args.args.first() {
573                            return extract_future_output(inner);
574                        }
575                    }
576                }
577            }
578            return None;
579        }
580        _ => return None,
581    };
582
583    for bound in bounds {
584        if let TypeParamBound::Trait(trait_bound) = bound {
585            if let Some(seg) = trait_bound.path.segments.last() {
586                if seg.ident == "Future" {
587                    if let PathArguments::AngleBracketed(args) = &seg.arguments {
588                        for arg in &args.args {
589                            if let GenericArgument::AssocType(assoc) = arg {
590                                if assoc.ident == "Output" {
591                                    return Some(assoc.ty.clone());
592                                }
593                            }
594                        }
595                    }
596                }
597            }
598        }
599    }
600    None
601}
602
603/// For HashMap<K,V> or BTreeMap<K,V>, returns Some((key_ty, value_ty)).
604fn extract_map_key_value(ty: &Type) -> Option<(Type, Type)> {
605    use syn::{GenericArgument, PathArguments};
606
607    if let Type::Path(tp) = ty {
608        if let Some(seg) = tp.path.segments.last() {
609            let ident_str = seg.ident.to_string();
610            if ident_str == "HashMap" || ident_str == "BTreeMap" {
611                if let PathArguments::AngleBracketed(ab) = &seg.arguments {
612                    let args: Vec<_> = ab.args.iter().collect();
613                    if let (Some(key_arg), Some(value_arg)) = (args.get(0), args.get(1)) {
614                        if let (GenericArgument::Type(key_ty), GenericArgument::Type(value_ty)) =
615                            (key_arg, value_arg)
616                        {
617                            return Some((key_ty.clone(), value_ty.clone()));
618                        }
619                    }
620                }
621            }
622        }
623    }
624    None
625}
626
627/// For `Option<HashMap<K,V>>` / `Option<BTreeMap<K,V>>`, returns `Some((key_ty, value_ty))`.
628fn extract_map_key_value_through_option(ty: &Type) -> Option<(Type, Type)> {
629    use syn::{GenericArgument, PathArguments};
630
631    if let Type::Path(tp) = ty {
632        if let Some(seg) = tp.path.segments.last() {
633            if seg.ident == "Option" {
634                if let PathArguments::AngleBracketed(ab) = &seg.arguments {
635                    if let Some(GenericArgument::Type(inner)) = ab.args.first() {
636                        return extract_map_key_value(inner);
637                    }
638                }
639            }
640        }
641    }
642    None
643}
644
645fn to_snake_case(name: &str) -> String {
646    let mut out = String::new();
647    for (i, c) in name.chars().enumerate() {
648        if c.is_uppercase() {
649            if i != 0 {
650                out.push('_');
651            }
652            out.push(c.to_ascii_lowercase());
653        } else {
654            out.push(c);
655        }
656    }
657    out
658}
659
660/// Derive macro for generating simple keypath methods.
661///
662/// Generates one method per field: `StructName::field_name()` that returns a `Kp`.
663/// Intelligently handles wrapper types (Option, Vec, Box, Arc, etc.) to generate appropriate keypaths.
664///
665/// # Example
666///
667/// ```ignore
668/// #[derive(Kp)]
669/// struct Person {
670///     name: String,
671///     age: i32,
672///     email: Option<String>,
673///     addresses: Vec<String>,
674/// }
675///
676/// // Generates:
677/// // impl Person {
678/// //     pub fn name() -> Kp<...> { ... }
679/// //     pub fn age() -> Kp<...> { ... }
680/// //     pub fn email() -> Kp<...> { ... } // unwraps Option
681/// //     pub fn addresses() -> Kp<...> { ... } // accesses first element
682/// // }
683/// ```
684#[proc_macro_derive(Kp)]
685pub fn derive_keypaths(input: TokenStream) -> TokenStream {
686    let input = parse_macro_input!(input as DeriveInput);
687    let name = &input.ident;
688    let input_span = input.span();
689
690    let methods = match input.data {
691        Data::Struct(data_struct) => match data_struct.fields {
692            Fields::Named(fields_named) => {
693                let mut tokens = proc_macro2::TokenStream::new();
694
695                // Generate identity methods for the struct
696                tokens.extend(quote! {
697                    /// Returns a generic identity keypath for this type
698                    #[inline(always)]
699                    pub fn _identity<'a, Root, MutRoot>() -> rust_key_paths::Kp<
700                        #name,
701                        #name,
702                        Root,
703                        Root,
704                        MutRoot,
705                        MutRoot,
706                        fn(Root) -> Option<Root>,
707                        fn(MutRoot) -> Option<MutRoot>,
708                    >
709                    where
710                        Root: std::borrow::Borrow<#name>,
711                        MutRoot: std::borrow::BorrowMut<#name>,
712                    {
713                        rust_key_paths::Kp::new(
714                            |r: Root| Some(r),
715                            |r: MutRoot| Some(r)
716                        )
717                    }
718
719                    // /// Returns a simple identity keypath for this type
720                    // #[inline(always)]
721                    // pub fn identity<'a>() -> rust_key_paths::Kp<#name, #name, &'a #name, &'a #name, &'a mut #name, &'a mut #name, impl Fn(&'a #name) -> Option<&'a #name>, impl Fn(&'a mut #name) -> Option<&'a mut #name>,> {
722                    //     rust_key_paths::Kp::new(
723                    //         |r: &#name| Some(r),
724                    //         |r: &mut #name| Some(r)
725                    //     )
726                    // }
727                });
728
729                // When struct has #[pin] fields, generated code calls this.project() which must
730                // be provided by #[pin_project]. If missing, user gets: no method named `project`.
731
732                for field in fields_named.named.iter() {
733                    let field_ident = field.ident.as_ref().unwrap();
734                    let ty = &field.ty;
735                    // Centralized keypath method names – change here to adjust for all types
736                    let kp_fn = format_ident!("{}", field_ident);
737                    let kp_at_fn = format_ident!("{}_at", field_ident);
738
739                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
740
741                    // Override kind when field has #[pin] (pin_project pattern)
742                    let (kind, inner_ty) = if field_has_pin_attr(field) {
743                        let pinned_kind = if let Some(output_ty) = extract_future_output(ty) {
744                            if matches!(kind, WrapperKind::Box) {
745                                (WrapperKind::PinnedBoxFuture, Some(output_ty))
746                            } else {
747                                (WrapperKind::PinnedFuture, Some(output_ty))
748                            }
749                        } else if is_future_type(ty) {
750                            (WrapperKind::PinnedFuture, inner_ty.clone())
751                        } else {
752                            (WrapperKind::PinnedField, inner_ty.clone())
753                        };
754                        pinned_kind
755                    } else {
756                        (kind, inner_ty.clone())
757                    };
758
759                    match (kind, inner_ty) {
760                        (WrapperKind::Option, Some(inner_ty)) => {
761                            // For Option<T>, unwrap and access inner type
762                            tokens.extend(quote! {
763                                #[inline(always)]
764                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
765    #name,
766    #inner_ty,
767    &'a #name,
768    &'a #inner_ty,
769    &'a mut #name,
770    &'a mut #inner_ty,
771    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
772    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
773> {
774                                    rust_key_paths::Kp::new(
775                                        |root: &#name| root.#field_ident.as_ref(),
776                                        |root: &mut #name| root.#field_ident.as_mut(),
777                                    )
778                                }
779                            });
780                        }
781                        (WrapperKind::OptionBox, Some(inner_ty)) => {
782                            // For Option<Box<T>>, keypath to T: get returns Option<&T> via as_deref()
783                            tokens.extend(quote! {
784                                #[inline(always)]
785                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
786    #name,
787    #inner_ty,
788    &'a #name,
789    &'a #inner_ty,
790    &'a mut #name,
791    &'a mut #inner_ty,
792    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
793    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
794> {
795                                    rust_key_paths::Kp::new(
796                                        |root: &#name| root.#field_ident.as_deref(),
797                                        |root: &mut #name| root.#field_ident.as_deref_mut(),
798                                    )
799                                }
800                            });
801                        }
802                        (WrapperKind::OptionRc, Some(inner_ty)) => {
803                            // For Option<Rc<T>>, keypath to T: get returns Option<&T> via as_deref()
804                            // Setter: as_mut() gives Option<&mut Rc<T>>, and_then(Rc::get_mut) gives Option<&mut T>
805                            tokens.extend(quote! {
806                                #[inline(always)]
807                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
808    #name,
809    #inner_ty,
810    &'a #name,
811    &'a #inner_ty,
812    &'a mut #name,
813    &'a mut #inner_ty,
814    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
815    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
816> {
817                                    rust_key_paths::Kp::new(
818                                        |root: &#name| root.#field_ident.as_deref(),
819                                        |root: &mut #name| root.#field_ident.as_mut().and_then(std::rc::Rc::get_mut),
820                                    )
821                                }
822                            });
823                        }
824                        (WrapperKind::OptionArc, Some(inner_ty)) => {
825                            // For Option<Arc<T>>, keypath to T: get returns Option<&T> via as_deref()
826                            // Setter: as_mut() gives Option<&mut Arc<T>>, and_then(Arc::get_mut) gives Option<&mut T>
827                            tokens.extend(quote! {
828                                #[inline(always)]
829                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
830    #name,
831    #inner_ty,
832    &'a #name,
833    &'a #inner_ty,
834    &'a mut #name,
835    &'a mut #inner_ty,
836    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
837    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
838> {
839                                    rust_key_paths::Kp::new(
840                                        |root: &#name| root.#field_ident.as_deref(),
841                                        |root: &mut #name| root.#field_ident.as_mut().and_then(std::sync::Arc::get_mut),
842                                    )
843                                }
844                            });
845                        }
846                        (WrapperKind::OptionHashMap, Some(inner_ty)) => {
847                            if let Some((key_ty, _)) = extract_map_key_value_through_option(ty) {
848                                let type_name = name.to_string();
849                                let whole_fn = kp_fn.to_string();
850                                let at_fn = kp_at_fn.to_string();
851                                let whole_doc = format!(
852                                    "Keypath to the whole optional `HashMap` (`{type_name}::{whole_fn}`). For a value at one key when the map is `Some`, use `{type_name}::{at_fn}(key)`."
853                                );
854                                let at_doc = format!(
855                                    "Keyed access into the inner `HashMap` (`{type_name}::{at_fn}`). `get`/`get_mut` return `None` if the field is `None` or the key is missing. See also `{type_name}::{whole_fn}` for the full optional map."
856                                );
857                                tokens.extend(quote! {
858                                    #[doc = #whole_doc]
859                                    #[inline(always)]
860                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
861    #name,
862    #ty,
863    &'a #name,
864    &'a #ty,
865    &'a mut #name,
866    &'a mut #ty,
867    impl Fn(&'a #name) -> Option<&'a #ty>,
868    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
869> {
870                                        rust_key_paths::Kp::new(
871                                            |root: &#name| Some(&root.#field_ident),
872                                            |root: &mut #name| Some(&mut root.#field_ident),
873                                        )
874                                    }
875                                    #[doc = #at_doc]
876                                    #[inline(always)]
877                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
878                                    where
879                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
880                                    {
881                                        let key2 = key.clone();
882                                        rust_key_paths::Kp::new(
883                                            Box::new(move |root: &#name| root.#field_ident.as_ref().and_then(|m| m.get(&key))),
884                                            Box::new(move |root: &mut #name| root.#field_ident.as_mut().and_then(|m| m.get_mut(&key2))),
885                                        )
886                                    }
887                                });
888                            } else {
889                                tokens.extend(quote! {
890                                    #[inline(always)]
891                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
892    #name,
893    #ty,
894    &'a #name,
895    &'a #ty,
896    &'a mut #name,
897    &'a mut #ty,
898    impl Fn(&'a #name) -> Option<&'a #ty>,
899    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
900> {
901                                        rust_key_paths::Kp::new(
902                                            |root: &#name| Some(&root.#field_ident),
903                                            |root: &mut #name| Some(&mut root.#field_ident),
904                                        )
905                                    }
906                                });
907                            }
908                        }
909                        (WrapperKind::OptionBTreeMap, Some(inner_ty)) => {
910                            if let Some((key_ty, _)) = extract_map_key_value_through_option(ty) {
911                                let type_name = name.to_string();
912                                let whole_fn = kp_fn.to_string();
913                                let at_fn = kp_at_fn.to_string();
914                                let whole_doc = format!(
915                                    "Keypath to the whole optional `BTreeMap` (`{type_name}::{whole_fn}`). For a value at one key when the map is `Some`, use `{type_name}::{at_fn}(key)`."
916                                );
917                                let at_doc = format!(
918                                    "Keyed access into the inner `BTreeMap` (`{type_name}::{at_fn}`). `get`/`get_mut` return `None` if the field is `None` or the key is missing. See also `{type_name}::{whole_fn}` for the full optional map."
919                                );
920                                tokens.extend(quote! {
921                                    #[doc = #whole_doc]
922                                    #[inline(always)]
923                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
924    #name,
925    #ty,
926    &'a #name,
927    &'a #ty,
928    &'a mut #name,
929    &'a mut #ty,
930    impl Fn(&'a #name) -> Option<&'a #ty>,
931    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
932> {
933                                        rust_key_paths::Kp::new(
934                                            |root: &#name| Some(&root.#field_ident),
935                                            |root: &mut #name| Some(&mut root.#field_ident),
936                                        )
937                                    }
938                                    #[doc = #at_doc]
939                                    #[inline(always)]
940                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
941                                    where
942                                        #key_ty: Clone + Ord + 'static,
943                                    {
944                                        let key2 = key.clone();
945                                        rust_key_paths::Kp::new(
946                                            Box::new(move |root: &#name| root.#field_ident.as_ref().and_then(|m| m.get(&key))),
947                                            Box::new(move |root: &mut #name| root.#field_ident.as_mut().and_then(|m| m.get_mut(&key2))),
948                                        )
949                                    }
950                                });
951                            } else {
952                                tokens.extend(quote! {
953                                    #[inline(always)]
954                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
955    #name,
956    #ty,
957    &'a #name,
958    &'a #ty,
959    &'a mut #name,
960    &'a mut #ty,
961    impl Fn(&'a #name) -> Option<&'a #ty>,
962    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
963> {
964                                        rust_key_paths::Kp::new(
965                                            |root: &#name| Some(&root.#field_ident),
966                                            |root: &mut #name| Some(&mut root.#field_ident),
967                                        )
968                                    }
969                                });
970                            }
971                        }
972                        (WrapperKind::OptionHashSet, Some(inner_ty)) => {
973                            tokens.extend(quote! {
974                                #[inline(always)]
975                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
976    #name,
977    #ty,
978    &'a #name,
979    &'a #ty,
980    &'a mut #name,
981    &'a mut #ty,
982    impl Fn(&'a #name) -> Option<&'a #ty>,
983    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
984> {
985                                    rust_key_paths::Kp::new(
986                                        |root: &#name| Some(&root.#field_ident),
987                                        |root: &mut #name| Some(&mut root.#field_ident),
988                                    )
989                                }
990
991                                /// _at: check if element exists and get reference.
992                                /// HashSet does not allow mutable element access (would break hash invariant).
993                                #[inline(always)]
994                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
995                                where
996                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
997                                {
998                                    rust_key_paths::Kp::new(
999                                        Box::new(move |root: &#name| root.#field_ident.as_ref().and_then(|s| s.get(&key))),
1000                                        Box::new(move |_root: &mut #name| None),
1001                                    )
1002                                }
1003                            });
1004                        }
1005                        (WrapperKind::OptionBTreeSet, Some(inner_ty)) => {
1006                            tokens.extend(quote! {
1007                                #[inline(always)]
1008                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1009    #name,
1010    #ty,
1011    &'a #name,
1012    &'a #ty,
1013    &'a mut #name,
1014    &'a mut #ty,
1015    impl Fn(&'a #name) -> Option<&'a #ty>,
1016    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1017> {
1018                                    rust_key_paths::Kp::new(
1019                                        |root: &#name| Some(&root.#field_ident),
1020                                        |root: &mut #name| Some(&mut root.#field_ident),
1021                                    )
1022                                }
1023
1024                                /// _at: check if element exists and get reference.
1025                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
1026                                #[inline(always)]
1027                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1028                                where
1029                                    #inner_ty: Clone + Ord + 'static,
1030                                {
1031                                    rust_key_paths::Kp::new(
1032                                        Box::new(move |root: &#name| root.#field_ident.as_ref().and_then(|s| s.get(&key))),
1033                                        Box::new(move |_root: &mut #name| None),
1034                                    )
1035                                }
1036                            });
1037                        }
1038                        (WrapperKind::OptionVec, Some(inner_ty)) => {
1039                            tokens.extend(quote! {
1040                                #[inline(always)]
1041                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1042    #name,
1043    #ty,
1044    &'a #name,
1045    &'a #ty,
1046    &'a mut #name,
1047    &'a mut #ty,
1048    impl Fn(&'a #name) -> Option<&'a #ty>,
1049    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1050> {
1051                                    rust_key_paths::Kp::new(
1052                                        |root: &#name| Some(&root.#field_ident),
1053                                        |root: &mut #name| Some(&mut root.#field_ident),
1054                                    )
1055                                }
1056                                #[inline(always)]
1057                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1058                                    rust_key_paths::Kp::new(
1059                                        Box::new(move |root: &#name| root.#field_ident.as_ref().and_then(|v| v.get(index))),
1060                                        Box::new(move |root: &mut #name| root.#field_ident.as_mut().and_then(|v| v.get_mut(index))),
1061                                    )
1062                                }
1063                            });
1064                        }
1065                        (WrapperKind::OptionVecDeque, Some(inner_ty)) => {
1066                            tokens.extend(quote! {
1067                                #[inline(always)]
1068                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1069    #name,
1070    #ty,
1071    &'a #name,
1072    &'a #ty,
1073    &'a mut #name,
1074    &'a mut #ty,
1075    impl Fn(&'a #name) -> Option<&'a #ty>,
1076    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1077> {
1078                                    rust_key_paths::Kp::new(
1079                                        |root: &#name| Some(&root.#field_ident),
1080                                        |root: &mut #name| Some(&mut root.#field_ident),
1081                                    )
1082                                }
1083                                #[inline(always)]
1084                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1085                                    rust_key_paths::Kp::new(
1086                                        Box::new(move |root: &#name| root.#field_ident.as_ref().and_then(|v| v.get(index))),
1087                                        Box::new(move |root: &mut #name| root.#field_ident.as_mut().and_then(|v| v.get_mut(index))),
1088                                    )
1089                                }
1090                            });
1091                        }
1092                        (WrapperKind::OptionLinkedList, Some(_inner_ty))
1093                        | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
1094                        | (WrapperKind::OptionResult, Some(_inner_ty)) => {
1095                            // Keypath to the Option container (reference), like Vec/HashSet
1096                            tokens.extend(quote! {
1097                                #[inline(always)]
1098                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1099    #name,
1100    #ty,
1101    &'a #name,
1102    &'a #ty,
1103    &'a mut #name,
1104    &'a mut #ty,
1105    impl Fn(&'a #name) -> Option<&'a #ty>,
1106    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1107> {
1108                                    rust_key_paths::Kp::new(
1109                                        |root: &#name| Some(&root.#field_ident),
1110                                        |root: &mut #name| Some(&mut root.#field_ident),
1111                                    )
1112                                }
1113                            });
1114                        }
1115                        (WrapperKind::Vec, Some(inner_ty)) => {
1116                            tokens.extend(quote! {
1117                                #[inline(always)]
1118                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1119    #name,
1120    #ty,
1121    &'a #name,
1122    &'a #ty,
1123    &'a mut #name,
1124    &'a mut #ty,
1125    impl Fn(&'a #name) -> Option<&'a #ty>,
1126    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1127> {
1128                                    rust_key_paths::Kp::new(
1129                                        |root: &#name| Some(&root.#field_ident),
1130                                        |root: &mut #name| Some(&mut root.#field_ident),
1131                                    )
1132                                }
1133                                #[inline(always)]
1134                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1135                                    rust_key_paths::Kp::new(
1136                                        Box::new(move |root: &#name| root.#field_ident.get(index)),
1137                                        Box::new(move |root: &mut #name| root.#field_ident.get_mut(index)),
1138                                    )
1139                                }
1140                            });
1141                        }
1142                        (WrapperKind::HashMap, Some(inner_ty)) => {
1143                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
1144                                tokens.extend(quote! {
1145                                    #[inline(always)]
1146                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1147    #name,
1148    #ty,
1149    &'a #name,
1150    &'a #ty,
1151    &'a mut #name,
1152    &'a mut #ty,
1153    impl Fn(&'a #name) -> Option<&'a #ty>,
1154    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1155> {
1156                                        rust_key_paths::Kp::new(
1157                                            |root: &#name| Some(&root.#field_ident),
1158                                            |root: &mut #name| Some(&mut root.#field_ident),
1159                                        )
1160                                    }
1161                                    #[inline(always)]
1162                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1163                                    where
1164                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
1165                                    {
1166                                        let key2 = key.clone();
1167                                        rust_key_paths::Kp::new(
1168                                            Box::new(move |root: &#name| root.#field_ident.get(&key)),
1169                                            Box::new(move |root: &mut #name| root.#field_ident.get_mut(&key2)),
1170                                        )
1171                                    }
1172                                });
1173                            } else {
1174                                tokens.extend(quote! {
1175                                    #[inline(always)]
1176                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1177    #name,
1178    #ty,
1179    &'a #name,
1180    &'a #ty,
1181    &'a mut #name,
1182    &'a mut #ty,
1183    impl Fn(&'a #name) -> Option<&'a #ty>,
1184    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1185> {
1186                                        rust_key_paths::Kp::new(
1187                                            |root: &#name| Some(&root.#field_ident),
1188                                            |root: &mut #name| Some(&mut root.#field_ident),
1189                                        )
1190                                    }
1191                                });
1192                            }
1193                        }
1194                        (WrapperKind::BTreeMap, Some(inner_ty))
1195                        | (WrapperKind::BTreeMapOption, Some(inner_ty)) => {
1196                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
1197                                tokens.extend(quote! {
1198                                    #[inline(always)]
1199                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1200    #name,
1201    #ty,
1202    &'a #name,
1203    &'a #ty,
1204    &'a mut #name,
1205    &'a mut #ty,
1206    impl Fn(&'a #name) -> Option<&'a #ty>,
1207    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1208> {
1209                                        rust_key_paths::Kp::new(
1210                                            |root: &#name| Some(&root.#field_ident),
1211                                            |root: &mut #name| Some(&mut root.#field_ident),
1212                                        )
1213                                    }
1214                                    #[inline(always)]
1215                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1216                                    where
1217                                        #key_ty: Clone + Ord + 'static,
1218                                    {
1219                                        let key2 = key.clone();
1220                                        rust_key_paths::Kp::new(
1221                                            Box::new(move |root: &#name| root.#field_ident.get(&key)),
1222                                            Box::new(move |root: &mut #name| root.#field_ident.get_mut(&key2)),
1223                                        )
1224                                    }
1225                                });
1226                            } else {
1227                                tokens.extend(quote! {
1228                                    #[inline(always)]
1229                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1230    #name,
1231    #ty,
1232    &'a #name,
1233    &'a #ty,
1234    &'a mut #name,
1235    &'a mut #ty,
1236    impl Fn(&'a #name) -> Option<&'a #ty>,
1237    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1238> {
1239                                        rust_key_paths::Kp::new(
1240                                            |root: &#name| Some(&root.#field_ident),
1241                                            |root: &mut #name| Some(&mut root.#field_ident),
1242                                        )
1243                                    }
1244                                });
1245                            }
1246                        }
1247                        (WrapperKind::Box, Some(inner_ty)) => {
1248                            // For Box<T>, deref to inner type (returns &T / &mut T, not &Box<T>)
1249                            tokens.extend(quote! {
1250                                #[inline(always)]
1251                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1252    #name,
1253    #inner_ty,
1254    &'a #name,
1255    &'a #inner_ty,
1256    &'a mut #name,
1257    &'a mut #inner_ty,
1258    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1259    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1260> {
1261                                    rust_key_paths::Kp::new(
1262                                        |root: &#name| Some(&*root.#field_ident),
1263                                        |root: &mut #name| Some(&mut *root.#field_ident),
1264                                    )
1265                                }
1266                            });
1267                        }
1268                        (WrapperKind::BoxOption, Some(inner_ty)) => {
1269                            // For Box<Option<T>>, keypath to T: deref Box to Option<T>, then Option::as_ref/as_mut
1270                            tokens.extend(quote! {
1271                                #[inline(always)]
1272                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1273    #name,
1274    #inner_ty,
1275    &'a #name,
1276    &'a #inner_ty,
1277    &'a mut #name,
1278    &'a mut #inner_ty,
1279    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1280    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1281> {
1282                                    rust_key_paths::Kp::new(
1283                                        |root: &#name| (&*root.#field_ident).as_ref(),
1284                                        |root: &mut #name| (&mut *root.#field_ident).as_mut(),
1285                                    )
1286                                }
1287                            });
1288                        }
1289                        (WrapperKind::RcOption, Some(inner_ty)) => {
1290                            // For Rc<Option<T>>, keypath to T: deref Rc to &Option<T>, then Option::as_ref; set = Rc::get_mut then as_mut
1291                            tokens.extend(quote! {
1292                                #[inline(always)]
1293                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1294    #name,
1295    #inner_ty,
1296    &'a #name,
1297    &'a #inner_ty,
1298    &'a mut #name,
1299    &'a mut #inner_ty,
1300    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1301    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1302> {
1303                                    rust_key_paths::Kp::new(
1304                                        |root: &#name| (&*root.#field_ident).as_ref(),
1305                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#field_ident).and_then(std::option::Option::as_mut),
1306                                    )
1307                                }
1308                            });
1309                        }
1310                        (WrapperKind::ArcOption, Some(inner_ty)) => {
1311                            // For Arc<Option<T>>, keypath to T: deref Arc to &Option<T>, then Option::as_ref; set = Arc::get_mut then as_mut
1312                            tokens.extend(quote! {
1313                                #[inline(always)]
1314                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1315    #name,
1316    #inner_ty,
1317    &'a #name,
1318    &'a #inner_ty,
1319    &'a mut #name,
1320    &'a mut #inner_ty,
1321    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1322    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1323> {
1324                                    rust_key_paths::Kp::new(
1325                                        |root: &#name| (&*root.#field_ident).as_ref(),
1326                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#field_ident).and_then(std::option::Option::as_mut),
1327                                    )
1328                                }
1329                            });
1330                        }
1331                        (WrapperKind::Pin, Some(inner_ty)) => {
1332                            let kp_inner_fn = format_ident!("{}_inner", field_ident);
1333                            tokens.extend(quote! {
1334                                #[inline(always)]
1335                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1336    #name,
1337    #ty,
1338    &'a #name,
1339    &'a #ty,
1340    &'a mut #name,
1341    &'a mut #ty,
1342    impl Fn(&'a #name) -> Option<&'a #ty>,
1343    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1344> {
1345                                    rust_key_paths::Kp::new(
1346                                        |root: &#name| Some(&root.#field_ident),
1347                                        |root: &mut #name| Some(&mut root.#field_ident),
1348                                    )
1349                                }
1350                                #[inline(always)]
1351                                pub fn #kp_inner_fn<'a>() -> rust_key_paths::Kp<
1352    #name,
1353    #inner_ty,
1354    &'a #name,
1355    &'a #inner_ty,
1356    &'a mut #name,
1357    &'a mut #inner_ty,
1358    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1359    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1360>
1361                                where #inner_ty: std::marker::Unpin
1362                                {
1363                                    rust_key_paths::Kp::new(
1364                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#field_ident).get_ref()),
1365                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#field_ident).get_mut()),
1366                                    )
1367                                }
1368                            });
1369                        }
1370                        (WrapperKind::PinBox, Some(inner_ty)) => {
1371                            let kp_inner_fn = format_ident!("{}_inner", field_ident);
1372                            tokens.extend(quote! {
1373                                #[inline(always)]
1374                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1375    #name,
1376    #ty,
1377    &'a #name,
1378    &'a #ty,
1379    &'a mut #name,
1380    &'a mut #ty,
1381    impl Fn(&'a #name) -> Option<&'a #ty>,
1382    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1383> {
1384                                    rust_key_paths::Kp::new(
1385                                        |root: &#name| Some(&root.#field_ident),
1386                                        |root: &mut #name| Some(&mut root.#field_ident),
1387                                    )
1388                                }
1389                                #[inline(always)]
1390                                pub fn #kp_inner_fn<'a>() -> rust_key_paths::Kp<
1391    #name,
1392    #inner_ty,
1393    &'a #name,
1394    &'a #inner_ty,
1395    &'a mut #name,
1396    &'a mut #inner_ty,
1397    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1398    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1399>
1400                                where #inner_ty: std::marker::Unpin
1401                                {
1402                                    // Pin::as_ref on Pin<Box<T>> returns Pin<&T> (Box Deref target), so get_ref() already gives &T
1403                                    rust_key_paths::Kp::new(
1404                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#field_ident).get_ref()),
1405                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#field_ident).get_mut()),
1406                                    )
1407                                }
1408                            });
1409                        }
1410                        (WrapperKind::PinnedField, _) => {
1411                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
1412                            tokens.extend(quote! {
1413                                #[inline(always)]
1414                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1415    #name,
1416    #ty,
1417    &'a #name,
1418    &'a #ty,
1419    &'a mut #name,
1420    &'a mut #ty,
1421    impl Fn(&'a #name) -> Option<&'a #ty>,
1422    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1423> {
1424                                    rust_key_paths::Kp::new(
1425                                        |root: &#name| Some(&root.#field_ident),
1426                                        |root: &mut #name| Some(&mut root.#field_ident),
1427                                    )
1428                                }
1429                                /// Pinned projection for #[pin] field. Requires #[pin_project] on struct.
1430                                #[inline(always)]
1431                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
1432                                    this.project().#field_ident
1433                                }
1434                            });
1435                        }
1436                        (WrapperKind::PinnedFuture, _) => {
1437                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
1438                            let kp_await_fn = format_ident!("{}_await", field_ident);
1439                            let kp_pin_future_fn = format_ident!("{}_pin_future_kp", field_ident);
1440                            let output_ty = quote! { <#ty as std::future::Future>::Output };
1441                            tokens.extend(quote! {
1442                                #[inline(always)]
1443                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1444    #name,
1445    #ty,
1446    &'a #name,
1447    &'a #ty,
1448    &'a mut #name,
1449    &'a mut #ty,
1450    impl Fn(&'a #name) -> Option<&'a #ty>,
1451    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1452> {
1453                                    rust_key_paths::Kp::new(
1454                                        |root: &#name| Some(&root.#field_ident),
1455                                        |root: &mut #name| Some(&mut root.#field_ident),
1456                                    )
1457                                }
1458                                /// Pinned projection for #[pin] Future field. Requires #[pin_project] on struct.
1459                                #[inline(always)]
1460                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
1461                                    this.project().#field_ident
1462                                }
1463                                /// Poll the pinned future. Requires #[pin_project] on struct.
1464                                pub async fn #kp_await_fn(this: std::pin::Pin<&mut #name>) -> Option<#output_ty>
1465                                where #ty: std::future::Future
1466                                {
1467                                    use std::future::Future;
1468                                    Some(this.project().#field_ident.await)
1469                                }
1470                                /// Keypath for [rust_key_paths::Kp::then_pin_future]. Composable pin future await.
1471                                #[inline(always)]
1472                                pub fn #kp_pin_future_fn() -> impl rust_key_paths::pin::PinFutureAwaitLike<#name, #output_ty> {
1473                                    rust_key_paths::pin_future_await_kp!(#name, #kp_await_fn -> #output_ty)
1474                                }
1475                            });
1476                        }
1477                        (WrapperKind::PinnedBoxFuture, Some(output_ty)) => {
1478                            let kp_pinned_fn = format_ident!("{}_pinned", field_ident);
1479                            let kp_await_fn = format_ident!("{}_await", field_ident);
1480                            let kp_pin_future_fn = format_ident!("{}_pin_future_kp", field_ident);
1481                            tokens.extend(quote! {
1482                                #[inline(always)]
1483                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1484    #name,
1485    #ty,
1486    &'a #name,
1487    &'a #ty,
1488    &'a mut #name,
1489    &'a mut #ty,
1490    impl Fn(&'a #name) -> Option<&'a #ty>,
1491    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1492> {
1493                                    rust_key_paths::Kp::new(
1494                                        |root: &#name| Some(&root.#field_ident),
1495                                        |root: &mut #name| Some(&mut root.#field_ident),
1496                                    )
1497                                }
1498                                /// Pinned projection for #[pin] Box<dyn Future> field. Requires #[pin_project] on struct.
1499                                #[inline(always)]
1500                                pub fn #kp_pinned_fn(this: std::pin::Pin<&mut #name>) -> std::pin::Pin<&mut #ty> {
1501                                    this.project().#field_ident
1502                                }
1503                                /// Poll the pinned boxed future. Requires #[pin_project] on struct.
1504                                pub async fn #kp_await_fn(this: std::pin::Pin<&mut #name>) -> Option<#output_ty> {
1505                                    Some(this.project().#field_ident.await)
1506                                }
1507                                /// Keypath for [rust_key_paths::Kp::then_pin_future]. Composable pin future await.
1508                                #[inline(always)]
1509                                pub fn #kp_pin_future_fn() -> impl rust_key_paths::pin::PinFutureAwaitLike<#name, #output_ty> {
1510                                    rust_key_paths::pin_future_await_kp!(#name, #kp_await_fn -> #output_ty)
1511                                }
1512                            });
1513                        }
1514                        (WrapperKind::Rc, Some(inner_ty)) => {
1515                            // For Rc<T>, deref to inner type (returns &T; get_mut when uniquely owned)
1516                            tokens.extend(quote! {
1517                                #[inline(always)]
1518                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1519    #name,
1520    #inner_ty,
1521    &'a #name,
1522    &'a #inner_ty,
1523    &'a mut #name,
1524    &'a mut #inner_ty,
1525    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1526    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1527> {
1528                                    rust_key_paths::Kp::new(
1529                                        |root: &#name| Some(root.#field_ident.as_ref()),
1530                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#field_ident),
1531                                    )
1532                                }
1533                            });
1534                        }
1535                        (WrapperKind::Arc, Some(inner_ty)) => {
1536                            // For Arc<T>, deref to inner type (returns &T; get_mut when uniquely owned)
1537                            tokens.extend(quote! {
1538                                #[inline(always)]
1539                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1540    #name,
1541    #inner_ty,
1542    &'a #name,
1543    &'a #inner_ty,
1544    &'a mut #name,
1545    &'a mut #inner_ty,
1546    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1547    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1548> {
1549                                    rust_key_paths::Kp::new(
1550                                        |root: &#name| Some(root.#field_ident.as_ref()),
1551                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#field_ident),
1552                                    )
1553                                }
1554                            });
1555                        }
1556                        (WrapperKind::Cow, Some(inner_ty)) => {
1557                            // For Cow<'_, B>, deref to inner type (as_ref/to_mut)
1558                            tokens.extend(quote! {
1559                                #[inline(always)]
1560                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1561    #name,
1562    #inner_ty,
1563    &'a #name,
1564    &'a #inner_ty,
1565    &'a mut #name,
1566    &'a mut #inner_ty,
1567    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1568    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1569> {
1570                                    rust_key_paths::Kp::new(
1571                                        |root: &#name| Some(root.#field_ident.as_ref()),
1572                                        |root: &mut #name| Some(root.#field_ident.to_mut()),
1573                                    )
1574                                }
1575                            });
1576                        }
1577
1578                        (WrapperKind::OptionCow, Some(inner_ty)) => {
1579                            // For Option<Cow<'_, B>>
1580                            tokens.extend(quote! {
1581                                #[inline(always)]
1582                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1583    #name,
1584    #inner_ty,
1585    &'a #name,
1586    &'a #inner_ty,
1587    &'a mut #name,
1588    &'a mut #inner_ty,
1589    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1590    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1591> {
1592                                    rust_key_paths::Kp::new(
1593                                        |root: &#name| root.#field_ident.as_ref().map(|c| c.as_ref()),
1594                                        |root: &mut #name| root.#field_ident.as_mut().map(|c| c.to_mut()),
1595                                    )
1596                                }
1597                            });
1598                        }
1599                        (WrapperKind::OptionTagged, Some(inner_ty)) => {
1600                            // For Option<Tagged<Tag, T>> - Tagged implements Deref/DerefMut
1601                            tokens.extend(quote! {
1602                                #[inline(always)]
1603                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1604    #name,
1605    #inner_ty,
1606    &'a #name,
1607    &'a #inner_ty,
1608    &'a mut #name,
1609    &'a mut #inner_ty,
1610    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1611    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1612> {
1613                                    rust_key_paths::Kp::new(
1614                                        |root: &#name| root.#field_ident.as_ref().map(|t| std::ops::Deref::deref(t)),
1615                                        |root: &mut #name| root.#field_ident.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
1616                                    )
1617                                }
1618                            });
1619                        }
1620                        (WrapperKind::OptionReference, Some(inner_ty)) => {
1621                            // For Option<&T>, Option<&str>, Option<&[T]> - read-only, setter returns None
1622                            tokens.extend(quote! {
1623                                #[inline(always)]
1624                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1625    #name,
1626    #inner_ty,
1627    &'a #name,
1628    &'a #inner_ty,
1629    &'a mut #name,
1630    &'a mut #inner_ty,
1631    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1632    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1633> {
1634                                    rust_key_paths::Kp::new(
1635                                        |root: &#name| root.#field_ident.as_ref(),
1636                                        |_root: &mut #name| None,
1637                                    )
1638                                }
1639                            });
1640                        }
1641                        (WrapperKind::HashSet, Some(inner_ty))
1642                        | (WrapperKind::HashSetOption, Some(inner_ty)) => {
1643                            let kp_at_fn = format_ident!("{}_at", field_ident);
1644
1645                            tokens.extend(quote! {
1646                                #[inline(always)]
1647                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1648    #name,
1649    #ty,
1650    &'a #name,
1651    &'a #ty,
1652    &'a mut #name,
1653    &'a mut #ty,
1654    impl Fn(&'a #name) -> Option<&'a #ty>,
1655    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1656> {
1657                                    rust_key_paths::Kp::new(
1658                                        |root: &#name| Some(&root.#field_ident),
1659                                        |root: &mut #name| Some(&mut root.#field_ident),
1660                                    )
1661                                }
1662
1663                                /// _at: check if element exists and get reference.
1664                                /// HashSet does not allow mutable element access (would break hash invariant).
1665                                #[inline(always)]
1666                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1667                                where
1668                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
1669                                {
1670                                    rust_key_paths::Kp::new(
1671                                        Box::new(move |root: &#name| root.#field_ident.get(&key)),
1672                                        Box::new(move |_root: &mut #name| None),
1673                                    )
1674                                }
1675                            });
1676                        }
1677                        (WrapperKind::BTreeSet, Some(inner_ty))
1678                        | (WrapperKind::BTreeSetOption, Some(inner_ty)) => {
1679                            let kp_at_fn = format_ident!("{}_at", field_ident);
1680
1681                            tokens.extend(quote! {
1682                                #[inline(always)]
1683                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1684    #name,
1685    #ty,
1686    &'a #name,
1687    &'a #ty,
1688    &'a mut #name,
1689    &'a mut #ty,
1690    impl Fn(&'a #name) -> Option<&'a #ty>,
1691    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1692> {
1693                                    rust_key_paths::Kp::new(
1694                                        |root: &#name| Some(&root.#field_ident),
1695                                        |root: &mut #name| Some(&mut root.#field_ident),
1696                                    )
1697                                }
1698
1699                                /// _at: check if element exists and get reference.
1700                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
1701                                #[inline(always)]
1702                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
1703                                where
1704                                    #inner_ty: Clone + Ord + 'static,
1705                                {
1706                                    rust_key_paths::Kp::new(
1707                                        Box::new(move |root: &#name| root.#field_ident.get(&key)),
1708                                        Box::new(move |_root: &mut #name| None),
1709                                    )
1710                                }
1711                            });
1712                        }
1713                        (WrapperKind::VecDeque, Some(inner_ty))
1714                        | (WrapperKind::VecDequeOption, Some(inner_ty)) => {
1715                            tokens.extend(quote! {
1716                                #[inline(always)]
1717                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1718    #name,
1719    #ty,
1720    &'a #name,
1721    &'a #ty,
1722    &'a mut #name,
1723    &'a mut #ty,
1724    impl Fn(&'a #name) -> Option<&'a #ty>,
1725    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1726> {
1727                                    rust_key_paths::Kp::new(
1728                                        |root: &#name| Some(&root.#field_ident),
1729                                        |root: &mut #name| Some(&mut root.#field_ident),
1730                                    )
1731                                }
1732                                #[inline(always)]
1733                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
1734                                    rust_key_paths::Kp::new(
1735                                        Box::new(move |root: &#name| root.#field_ident.get(index)),
1736                                        Box::new(move |root: &mut #name| root.#field_ident.get_mut(index)),
1737                                    )
1738                                }
1739                            });
1740                        }
1741                        (WrapperKind::LinkedList, Some(_inner_ty))
1742                        | (WrapperKind::LinkedListOption, Some(_inner_ty)) => {
1743                            tokens.extend(quote! {
1744                                #[inline(always)]
1745                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1746    #name,
1747    #ty,
1748    &'a #name,
1749    &'a #ty,
1750    &'a mut #name,
1751    &'a mut #ty,
1752    impl Fn(&'a #name) -> Option<&'a #ty>,
1753    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1754> {
1755                                    rust_key_paths::Kp::new(
1756                                        |root: &#name| Some(&root.#field_ident),
1757                                        |root: &mut #name| Some(&mut root.#field_ident),
1758                                    )
1759                                }
1760                            });
1761                        }
1762                        (WrapperKind::BinaryHeap, Some(_inner_ty))
1763                        | (WrapperKind::BinaryHeapOption, Some(_inner_ty)) => {
1764                            tokens.extend(quote! {
1765                                #[inline(always)]
1766                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1767    #name,
1768    #ty,
1769    &'a #name,
1770    &'a #ty,
1771    &'a mut #name,
1772    &'a mut #ty,
1773    impl Fn(&'a #name) -> Option<&'a #ty>,
1774    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1775> {
1776                                    rust_key_paths::Kp::new(
1777                                        |root: &#name| Some(&root.#field_ident),
1778                                        |root: &mut #name| Some(&mut root.#field_ident),
1779                                    )
1780                                }
1781                            });
1782                        }
1783                        (WrapperKind::Result, Some(inner_ty)) => {
1784                            // For Result<T, E>, access Ok value
1785                            tokens.extend(quote! {
1786                                #[inline(always)]
1787                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
1788    #name,
1789    #inner_ty,
1790    &'a #name,
1791    &'a #inner_ty,
1792    &'a mut #name,
1793    &'a mut #inner_ty,
1794    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
1795    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
1796> {
1797                                    rust_key_paths::Kp::new(
1798                                        |root: &#name| root.#field_ident.as_ref().ok(),
1799                                        |root: &mut #name| root.#field_ident.as_mut().ok(),
1800                                    )
1801                                }
1802                            });
1803                        }
1804                        (WrapperKind::StdArcMutex, Some(inner_ty)) => {
1805                            // For Arc<std::sync::Mutex<T>>
1806                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1807                            tokens.extend(quote! {
1808                                #[inline(always)]
1809                                    pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
1810    #name,
1811    #ty,
1812    &'a #name,
1813    &'a #ty,
1814    &'a mut #name,
1815    &'a mut #ty,
1816    impl Fn(&'a #name) -> Option<&'a #ty>,
1817    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1818> {
1819                                    rust_key_paths::Kp::new(
1820                                        |root: &#name| Some(&root.#field_ident),
1821                                        |root: &mut #name| Some(&mut root.#field_ident),
1822                                    )
1823                                }
1824                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcMutexFor<#name, #ty, #inner_ty> {
1825                                    rust_key_paths::lock::LockKp::new(
1826                                        rust_key_paths::Kp::new(
1827                                            |root: &#name| Some(&root.#field_ident),
1828                                            |root: &mut #name| Some(&mut root.#field_ident),
1829                                        ),
1830                                        rust_key_paths::lock::ArcMutexAccess::new(),
1831                                        rust_key_paths::Kp::new(
1832                                            |v: &#inner_ty| Some(v),
1833                                            |v: &mut #inner_ty| Some(v),
1834                                        ),
1835                                    )
1836                                }
1837                            });
1838                        }
1839                        (WrapperKind::StdArcRwLock, Some(inner_ty)) => {
1840                            // For Arc<std::sync::RwLock<T>>
1841                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1842                            tokens.extend(quote! {
1843                                #[inline(always)]
1844                                    pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
1845    #name,
1846    #ty,
1847    &'a #name,
1848    &'a #ty,
1849    &'a mut #name,
1850    &'a mut #ty,
1851    impl Fn(&'a #name) -> Option<&'a #ty>,
1852    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1853> {
1854                                    rust_key_paths::Kp::new(
1855                                        |root: &#name| Some(&root.#field_ident),
1856                                        |root: &mut #name| Some(&mut root.#field_ident),
1857                                    )
1858                                }
1859                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, #ty, #inner_ty> {
1860                                    rust_key_paths::lock::LockKp::new(
1861                                        rust_key_paths::Kp::new(
1862                                            |root: &#name| Some(&root.#field_ident),
1863                                            |root: &mut #name| Some(&mut root.#field_ident),
1864                                        ),
1865                                        rust_key_paths::lock::ArcRwLockAccess::new(),
1866                                        rust_key_paths::Kp::new(
1867                                            |v: &#inner_ty| Some(v),
1868                                            |v: &mut #inner_ty| Some(v),
1869                                        ),
1870                                    )
1871                                }
1872                            });
1873                        }
1874                        (WrapperKind::StdArcMutexOption, Some(inner_ty)) => {
1875                            // For Arc<std::sync::Mutex<Option<T>>> — LockKp value T (extract from Option); guard gives &Option<T>
1876                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1877                            tokens.extend(quote! {
1878                                #[inline(always)]
1879                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
1880    #name,
1881    #ty,
1882    &'a #name,
1883    &'a #ty,
1884    &'a mut #name,
1885    &'a mut #ty,
1886    impl Fn(&'a #name) -> Option<&'a #ty>,
1887    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1888> {
1889                                    rust_key_paths::Kp::new(
1890                                        |root: &#name| Some(&root.#field_ident),
1891                                        |root: &mut #name| Some(&mut root.#field_ident),
1892                                    )
1893                                }
1894                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcMutexOptionFor<#name, #ty, #inner_ty> {
1895                                    rust_key_paths::lock::LockKp::new(
1896                                        rust_key_paths::Kp::new(
1897                                            |root: &#name| Some(&root.#field_ident),
1898                                            |root: &mut #name| Some(&mut root.#field_ident),
1899                                        ),
1900                                        rust_key_paths::lock::ArcMutexAccess::<Option<#inner_ty>>::new(),
1901                                        rust_key_paths::Kp::new(
1902                                            Option::<#inner_ty>::as_ref,
1903                                            Option::<#inner_ty>::as_mut,
1904                                        ),
1905                                    )
1906                                }
1907                            });
1908                        }
1909                        (WrapperKind::StdArcRwLockOption, Some(inner_ty)) => {
1910                            // For Arc<std::sync::RwLock<Option<T>>> — LockKp value T (extract from Option); guard gives &Option<T>
1911                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1912                            tokens.extend(quote! {
1913                                #[inline(always)]
1914                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
1915    #name,
1916    #ty,
1917    &'a #name,
1918    &'a #ty,
1919    &'a mut #name,
1920    &'a mut #ty,
1921    impl Fn(&'a #name) -> Option<&'a #ty>,
1922    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1923> {
1924                                    rust_key_paths::Kp::new(
1925                                        |root: &#name| Some(&root.#field_ident),
1926                                        |root: &mut #name| Some(&mut root.#field_ident),
1927                                    )
1928                                }
1929                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcRwLockOptionFor<#name, #ty, #inner_ty> {
1930                                    rust_key_paths::lock::LockKp::new(
1931                                        rust_key_paths::Kp::new(
1932                                            |root: &#name| Some(&root.#field_ident),
1933                                            |root: &mut #name| Some(&mut root.#field_ident),
1934                                        ),
1935                                        rust_key_paths::lock::ArcRwLockAccess::<Option<#inner_ty>>::new(),
1936                                        rust_key_paths::Kp::new(
1937                                            Option::<#inner_ty>::as_ref,
1938                                            Option::<#inner_ty>::as_mut,
1939                                        ),
1940                                    )
1941                                }
1942                            });
1943                        }
1944                        (WrapperKind::ArcRwLock, Some(inner_ty)) => {
1945                            // For Arc<parking_lot::RwLock<T>> (requires rust-key-paths "parking_lot" feature)
1946                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1947                            tokens.extend(quote! {
1948                                #[inline(always)]
1949                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
1950    #name,
1951    #ty,
1952    &'a #name,
1953    &'a #ty,
1954    &'a mut #name,
1955    &'a mut #ty,
1956    impl Fn(&'a #name) -> Option<&'a #ty>,
1957    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1958> {
1959                                    rust_key_paths::Kp::new(
1960                                        |root: &#name| Some(&root.#field_ident),
1961                                        |root: &mut #name| Some(&mut root.#field_ident),
1962                                    )
1963                                }
1964                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, #ty, #inner_ty> {
1965                                    rust_key_paths::lock::LockKp::new(
1966                                        rust_key_paths::Kp::new(
1967                                            |root: &#name| Some(&root.#field_ident),
1968                                            |root: &mut #name| Some(&mut root.#field_ident),
1969                                        ),
1970                                        rust_key_paths::lock::ParkingLotRwLockAccess::new(),
1971                                        rust_key_paths::Kp::new(
1972                                            |v: &#inner_ty| Some(v),
1973                                            |v: &mut #inner_ty| Some(v),
1974                                        ),
1975                                    )
1976                                }
1977                            });
1978                        }
1979                        (WrapperKind::ArcMutex, Some(inner_ty)) => {
1980                            // For Arc<parking_lot::Mutex<T>> (requires rust-key-paths "parking_lot" feature)
1981                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
1982                            tokens.extend(quote! {
1983                                #[inline(always)]
1984                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
1985    #name,
1986    #ty,
1987    &'a #name,
1988    &'a #ty,
1989    &'a mut #name,
1990    &'a mut #ty,
1991    impl Fn(&'a #name) -> Option<&'a #ty>,
1992    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
1993> {
1994                                    rust_key_paths::Kp::new(
1995                                        |root: &#name| Some(&root.#field_ident),
1996                                        |root: &mut #name| Some(&mut root.#field_ident),
1997                                    )
1998                                }
1999                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, #ty, #inner_ty> {
2000                                    rust_key_paths::lock::LockKp::new(
2001                                        rust_key_paths::Kp::new(
2002                                            |root: &#name| Some(&root.#field_ident),
2003                                            |root: &mut #name| Some(&mut root.#field_ident),
2004                                        ),
2005                                        rust_key_paths::lock::ParkingLotMutexAccess::new(),
2006                                        rust_key_paths::Kp::new(
2007                                            |v: &#inner_ty| Some(v),
2008                                            |v: &mut #inner_ty| Some(v),
2009                                        ),
2010                                    )
2011                                }
2012                            });
2013                        }
2014                        (WrapperKind::ArcMutexOption, Some(inner_ty)) => {
2015                            // For Arc<parking_lot::Mutex<Option<T>>> — LockKp value T (extract from Option); guard gives &Option<T>
2016                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
2017                            tokens.extend(quote! {
2018                                #[inline(always)]
2019                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
2020    #name,
2021    #ty,
2022    &'a #name,
2023    &'a #ty,
2024    &'a mut #name,
2025    &'a mut #ty,
2026    impl Fn(&'a #name) -> Option<&'a #ty>,
2027    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2028> {
2029                                    rust_key_paths::Kp::new(
2030                                        |root: &#name| Some(&root.#field_ident),
2031                                        |root: &mut #name| Some(&mut root.#field_ident),
2032                                    )
2033                                }
2034                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotMutexOptionFor<#name, #ty, #inner_ty> {
2035                                    rust_key_paths::lock::LockKp::new(
2036                                        rust_key_paths::Kp::new(
2037                                            |root: &#name| Some(&root.#field_ident),
2038                                            |root: &mut #name| Some(&mut root.#field_ident),
2039                                        ),
2040                                        rust_key_paths::lock::ParkingLotMutexAccess::<Option<#inner_ty>>::new(),
2041                                        rust_key_paths::Kp::new(
2042                                            Option::<#inner_ty>::as_ref,
2043                                            Option::<#inner_ty>::as_mut,
2044                                        ),
2045                                    )
2046                                }
2047                            });
2048                        }
2049                        (WrapperKind::ArcRwLockOption, Some(inner_ty)) => {
2050                            // For Arc<parking_lot::RwLock<Option<T>>> — LockKp value T (extract from Option); guard gives &Option<T>
2051                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
2052                            tokens.extend(quote! {
2053                                #[inline(always)]
2054                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
2055    #name,
2056    #ty,
2057    &'a #name,
2058    &'a #ty,
2059    &'a mut #name,
2060    &'a mut #ty,
2061    impl Fn(&'a #name) -> Option<&'a #ty>,
2062    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2063> {
2064                                    rust_key_paths::Kp::new(
2065                                        |root: &#name| Some(&root.#field_ident),
2066                                        |root: &mut #name| Some(&mut root.#field_ident),
2067                                    )
2068                                }
2069                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockOptionFor<#name, #ty, #inner_ty> {
2070                                    rust_key_paths::lock::LockKp::new(
2071                                        rust_key_paths::Kp::new(
2072                                            |root: &#name| Some(&root.#field_ident),
2073                                            |root: &mut #name| Some(&mut root.#field_ident),
2074                                        ),
2075                                        rust_key_paths::lock::ParkingLotRwLockAccess::<Option<#inner_ty>>::new(),
2076                                        rust_key_paths::Kp::new(
2077                                            Option::<#inner_ty>::as_ref,
2078                                            Option::<#inner_ty>::as_mut,
2079                                        ),
2080                                    )
2081                                }
2082                            });
2083                        }
2084                        (WrapperKind::Mutex, Some(_inner_ty))
2085                        | (WrapperKind::StdMutex, Some(_inner_ty)) => {
2086                            // For Mutex<T>, return keypath to container
2087                            tokens.extend(quote! {
2088                                #[inline(always)]
2089                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2090    #name,
2091    #ty,
2092    &'a #name,
2093    &'a #ty,
2094    &'a mut #name,
2095    &'a mut #ty,
2096    impl Fn(&'a #name) -> Option<&'a #ty>,
2097    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2098> {
2099                                    rust_key_paths::Kp::new(
2100                                        |root: &#name| Some(&root.#field_ident),
2101                                        |root: &mut #name| Some(&mut root.#field_ident),
2102                                    )
2103                                }
2104                            });
2105                        }
2106                        (WrapperKind::RwLock, Some(_inner_ty))
2107                        | (WrapperKind::StdRwLock, Some(_inner_ty)) => {
2108                            // For RwLock<T>, return keypath to container
2109                            tokens.extend(quote! {
2110                                #[inline(always)]
2111                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2112    #name,
2113    #ty,
2114    &'a #name,
2115    &'a #ty,
2116    &'a mut #name,
2117    &'a mut #ty,
2118    impl Fn(&'a #name) -> Option<&'a #ty>,
2119    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2120> {
2121                                    rust_key_paths::Kp::new(
2122                                        |root: &#name| Some(&root.#field_ident),
2123                                        |root: &mut #name| Some(&mut root.#field_ident),
2124                                    )
2125                                }
2126                            });
2127                        }
2128                        (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
2129                            let kp_async_fn = format_ident!("{}_kp", field_ident);
2130                            tokens.extend(quote! {
2131                                #[inline(always)]
2132                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
2133    #name,
2134    #ty,
2135    &'a #name,
2136    &'a #ty,
2137    &'a mut #name,
2138    &'a mut #ty,
2139    impl Fn(&'a #name) -> Option<&'a #ty>,
2140    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2141> {
2142                                    rust_key_paths::Kp::new(
2143                                        |root: &#name| Some(&root.#field_ident),
2144                                        |root: &mut #name| Some(&mut root.#field_ident),
2145                                    )
2146                                }
2147                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #ty, #inner_ty> {
2148                                    rust_key_paths::async_lock::AsyncLockKp::new(
2149                                        rust_key_paths::Kp::new(
2150                                            |root: &#name| Some(&root.#field_ident),
2151                                            |root: &mut #name| Some(&mut root.#field_ident),
2152                                        ),
2153                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
2154                                        rust_key_paths::Kp::new(
2155                                            |v: &#inner_ty| Some(v),
2156                                            |v: &mut #inner_ty| Some(v),
2157                                        ),
2158                                    )
2159                                }
2160                            });
2161                        }
2162                        (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
2163                            let kp_async_fn = format_ident!("{}_kp", field_ident);
2164                            tokens.extend(quote! {
2165                                #[inline(always)]
2166                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
2167    #name,
2168    #ty,
2169    &'a #name,
2170    &'a #ty,
2171    &'a mut #name,
2172    &'a mut #ty,
2173    impl Fn(&'a #name) -> Option<&'a #ty>,
2174    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2175> {
2176                                    rust_key_paths::Kp::new(
2177                                        |root: &#name| Some(&root.#field_ident),
2178                                        |root: &mut #name| Some(&mut root.#field_ident),
2179                                    )
2180                                }
2181                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #ty, #inner_ty> {
2182                                    rust_key_paths::async_lock::AsyncLockKp::new(
2183                                        rust_key_paths::Kp::new(
2184                                            |root: &#name| Some(&root.#field_ident),
2185                                            |root: &mut #name| Some(&mut root.#field_ident),
2186                                        ),
2187                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
2188                                        rust_key_paths::Kp::new(
2189                                            |v: &#inner_ty| Some(v),
2190                                            |v: &mut #inner_ty| Some(v),
2191                                        ),
2192                                    )
2193                                }
2194                            });
2195                        }
2196                        (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
2197                            let kp_async_fn = format_ident!("{}_kp", field_ident);
2198                            tokens.extend(quote! {
2199                                #[inline(always)]
2200                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
2201    #name,
2202    #ty,
2203    &'a #name,
2204    &'a #ty,
2205    &'a mut #name,
2206    &'a mut #ty,
2207    impl Fn(&'a #name) -> Option<&'a #ty>,
2208    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2209> {
2210                                    rust_key_paths::Kp::new(
2211                                        |root: &#name| Some(&root.#field_ident),
2212                                        |root: &mut #name| Some(&mut root.#field_ident),
2213                                    )
2214                                }
2215                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
2216                                    rust_key_paths::async_lock::AsyncLockKp::new(
2217                                        rust_key_paths::Kp::new(
2218                                            |root: &#name| root.#field_ident.as_ref(),
2219                                            |root: &mut #name| root.#field_ident.as_mut(),
2220                                        ),
2221                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
2222                                        rust_key_paths::Kp::new(
2223                                            |v: &#inner_ty| Some(v),
2224                                            |v: &mut #inner_ty| Some(v),
2225                                        ),
2226                                    )
2227                                }
2228                            });
2229                        }
2230                        (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
2231                            let kp_async_fn = format_ident!("{}_kp", field_ident);
2232                            tokens.extend(quote! {
2233                                #[inline(always)]
2234                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
2235    #name,
2236    #ty,
2237    &'a #name,
2238    &'a #ty,
2239    &'a mut #name,
2240    &'a mut #ty,
2241    impl Fn(&'a #name) -> Option<&'a #ty>,
2242    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2243> {
2244                                    rust_key_paths::Kp::new(
2245                                        |root: &#name| Some(&root.#field_ident),
2246                                        |root: &mut #name| Some(&mut root.#field_ident),
2247                                    )
2248                                }
2249                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
2250                                    rust_key_paths::async_lock::AsyncLockKp::new(
2251                                        rust_key_paths::Kp::new(
2252                                            |root: &#name| root.#field_ident.as_ref(),
2253                                            |root: &mut #name| root.#field_ident.as_mut(),
2254                                        ),
2255                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
2256                                        rust_key_paths::Kp::new(
2257                                            |v: &#inner_ty| Some(v),
2258                                            |v: &mut #inner_ty| Some(v),
2259                                        ),
2260                                    )
2261                                }
2262                            });
2263                        }
2264                        (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
2265                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2266                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
2267                            tokens.extend(quote! {
2268                                #[inline(always)]
2269                                    pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
2270    #name,
2271    #ty,
2272    &'a #name,
2273    &'a #ty,
2274    &'a mut #name,
2275    &'a mut #ty,
2276    impl Fn(&'a #name) -> Option<&'a #ty>,
2277    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2278> {
2279                                    rust_key_paths::Kp::new(
2280                                        |root: &#name| Some(&root.#field_ident),
2281                                        |root: &mut #name| Some(&mut root.#field_ident),
2282                                    )
2283                                }
2284                                // pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, &'a #name, &'a std::sync::Arc<std::sync::Mutex<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<std::sync::Mutex<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<std::sync::Mutex<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<std::sync::Mutex<#inner_ty>>>,> {
2285                                //     rust_key_paths::Kp::new(
2286                                //         |root: &#name| root.#field_ident.as_ref(),
2287                                //         |root: &mut #name| root.#field_ident.as_mut(),
2288                                //     )
2289                                // }
2290                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcMutexFor<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, #inner_ty> {
2291                                    rust_key_paths::lock::LockKp::new(
2292                                        rust_key_paths::Kp::new(
2293                                            |root: &#name| root.#field_ident.as_ref(),
2294                                            |root: &mut #name| root.#field_ident.as_mut(),
2295                                        ),
2296                                        rust_key_paths::lock::ArcMutexAccess::new(),
2297                                        rust_key_paths::Kp::new(
2298                                            |v: &#inner_ty| Some(v),
2299                                            |v: &mut #inner_ty| Some(v),
2300                                        ),
2301                                    )
2302                                }
2303                            });
2304                        }
2305                        (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
2306                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2307                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
2308                            tokens.extend(quote! {
2309                                #[inline(always)]
2310                                pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
2311    #name,
2312    #ty,
2313    &'a #name,
2314    &'a #ty,
2315    &'a mut #name,
2316    &'a mut #ty,
2317    impl Fn(&'a #name) -> Option<&'a #ty>,
2318    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2319> {
2320                                    rust_key_paths::Kp::new(
2321                                        |root: &#name| Some(&root.#field_ident),
2322                                        |root: &mut #name| Some(&mut root.#field_ident),
2323                                    )
2324                                }
2325                                // pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, &'a #name, &'a std::sync::Arc<parking_lot::Mutex<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<parking_lot::Mutex<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<parking_lot::Mutex<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<parking_lot::Mutex<#inner_ty>>>,> {
2326                                //     rust_key_paths::Kp::new(
2327                                //         |root: &#name| root.#field_ident.as_ref(),
2328                                //         |root: &mut #name| root.#field_ident.as_mut(),
2329                                //     )
2330                                // }
2331                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, #inner_ty> {
2332                                    rust_key_paths::lock::LockKp::new(
2333                                        rust_key_paths::Kp::new(
2334                                            |root: &#name| root.#field_ident.as_ref(),
2335                                            |root: &mut #name| root.#field_ident.as_mut(),
2336                                        ),
2337                                        rust_key_paths::lock::ParkingLotMutexAccess::new(),
2338                                        rust_key_paths::Kp::new(
2339                                            |v: &#inner_ty| Some(v),
2340                                            |v: &mut #inner_ty| Some(v),
2341                                        ),
2342                                    )
2343                                }
2344                            });
2345                        }
2346                        (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
2347                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2348                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
2349                            tokens.extend(quote! {
2350                                #[inline(always)]
2351                                    pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
2352    #name,
2353    #ty,
2354    &'a #name,
2355    &'a #ty,
2356    &'a mut #name,
2357    &'a mut #ty,
2358    impl Fn(&'a #name) -> Option<&'a #ty>,
2359    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2360> {
2361                                    rust_key_paths::Kp::new(
2362                                        |root: &#name| Some(&root.#field_ident),
2363                                        |root: &mut #name| Some(&mut root.#field_ident),
2364                                    )
2365                                }
2366                                // pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, &'a #name, &'a std::sync::Arc<std::sync::RwLock<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<std::sync::RwLock<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<std::sync::RwLock<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<std::sync::RwLock<#inner_ty>>>,> {
2367                                //     rust_key_paths::Kp::new(
2368                                //         |root: &#name| root.#field_ident.as_ref(),
2369                                //         |root: &mut #name| root.#field_ident.as_mut(),
2370                                //     )
2371                                // }
2372                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, #inner_ty> {
2373                                    rust_key_paths::lock::LockKp::new(
2374                                        rust_key_paths::Kp::new(
2375                                            |root: &#name| root.#field_ident.as_ref(),
2376                                            |root: &mut #name| root.#field_ident.as_mut(),
2377                                        ),
2378                                        rust_key_paths::lock::ArcRwLockAccess::new(),
2379                                        rust_key_paths::Kp::new(
2380                                            |v: &#inner_ty| Some(v),
2381                                            |v: &mut #inner_ty| Some(v),
2382                                        ),
2383                                    )
2384                                }
2385                            });
2386                        }
2387                        (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
2388                            // let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2389                            let kp_lock_fn = format_ident!("{}_kp", field_ident);
2390                            tokens.extend(quote! {
2391                                #[inline(always)]
2392                                    pub fn #kp_lock_fn<'a>() -> rust_key_paths::Kp<
2393    #name,
2394    #ty,
2395    &'a #name,
2396    &'a #ty,
2397    &'a mut #name,
2398    &'a mut #ty,
2399    impl Fn(&'a #name) -> Option<&'a #ty>,
2400    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2401> {
2402                                    rust_key_paths::Kp::new(
2403                                        |root: &#name| Some(&root.#field_ident),
2404                                        |root: &mut #name| Some(&mut root.#field_ident),
2405                                    )
2406                                }
2407                                // pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, &'a #name, &'a std::sync::Arc<parking_lot::RwLock<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<parking_lot::RwLock<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<parking_lot::RwLock<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<parking_lot::RwLock<#inner_ty>>>,> {
2408                                //     rust_key_paths::Kp::new(
2409                                //         |root: &#name| root.#field_ident.as_ref(),
2410                                //         |root: &mut #name| root.#field_ident.as_mut(),
2411                                //     )
2412                                // }
2413                                pub fn #kp_fn() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, #inner_ty> {
2414                                    rust_key_paths::lock::LockKp::new(
2415                                        rust_key_paths::Kp::new(
2416                                            |root: &#name| root.#field_ident.as_ref(),
2417                                            |root: &mut #name| root.#field_ident.as_mut(),
2418                                        ),
2419                                        rust_key_paths::lock::ParkingLotRwLockAccess::new(),
2420                                        rust_key_paths::Kp::new(
2421                                            |v: &#inner_ty| Some(v),
2422                                            |v: &mut #inner_ty| Some(v),
2423                                        ),
2424                                    )
2425                                }
2426                            });
2427                        }
2428                        (WrapperKind::OptionStdMutex, Some(inner_ty)) => {
2429                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2430                            tokens.extend(quote! {
2431                                #[inline(always)]
2432                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2433    #name,
2434    #ty,
2435    &'a #name,
2436    &'a #ty,
2437    &'a mut #name,
2438    &'a mut #ty,
2439    impl Fn(&'a #name) -> Option<&'a #ty>,
2440    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2441> {
2442                                    rust_key_paths::Kp::new(
2443                                        |root: &#name| Some(&root.#field_ident),
2444                                        |root: &mut #name| Some(&mut root.#field_ident),
2445                                    )
2446                                }
2447                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
2448    #name,
2449    std::sync::Mutex<#inner_ty>,
2450    &'a #name,
2451    &'a std::sync::Mutex<#inner_ty>,
2452    &'a mut #name,
2453    &'a mut std::sync::Mutex<#inner_ty>,
2454    impl Fn(&'a #name) -> Option<&'a std::sync::Mutex<#inner_ty>>,
2455    impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Mutex<#inner_ty>>,
2456> {
2457                                    rust_key_paths::Kp::new(
2458                                        |root: &#name| root.#field_ident.as_ref(),
2459                                        |root: &mut #name| root.#field_ident.as_mut(),
2460                                    )
2461                                }
2462                            });
2463                        }
2464                        (WrapperKind::OptionMutex, Some(inner_ty)) => {
2465                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2466                            tokens.extend(quote! {
2467                                #[inline(always)]
2468                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2469    #name,
2470    #ty,
2471    &'a #name,
2472    &'a #ty,
2473    &'a mut #name,
2474    &'a mut #ty,
2475    impl Fn(&'a #name) -> Option<&'a #ty>,
2476    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2477> {
2478                                    rust_key_paths::Kp::new(
2479                                        |root: &#name| Some(&root.#field_ident),
2480                                        |root: &mut #name| Some(&mut root.#field_ident),
2481                                    )
2482                                }
2483                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
2484    #name,
2485    parking_lot::Mutex<#inner_ty>,
2486    &'a #name,
2487    &'a parking_lot::Mutex<#inner_ty>,
2488    &'a mut #name,
2489    &'a mut parking_lot::Mutex<#inner_ty>,
2490    impl Fn(&'a #name) -> Option<&'a parking_lot::Mutex<#inner_ty>>,
2491    impl Fn(&'a mut #name) -> Option<&'a mut parking_lot::Mutex<#inner_ty>>,
2492> {
2493                                    rust_key_paths::Kp::new(
2494                                        |root: &#name| root.#field_ident.as_ref(),
2495                                        |root: &mut #name| root.#field_ident.as_mut(),
2496                                    )
2497                                }
2498                            });
2499                        }
2500                        (WrapperKind::OptionStdRwLock, Some(inner_ty)) => {
2501                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2502                            tokens.extend(quote! {
2503                                #[inline(always)]
2504                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2505    #name,
2506    #ty,
2507    &'a #name,
2508    &'a #ty,
2509    &'a mut #name,
2510    &'a mut #ty,
2511    impl Fn(&'a #name) -> Option<&'a #ty>,
2512    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2513> {
2514                                    rust_key_paths::Kp::new(
2515                                        |root: &#name| Some(&root.#field_ident),
2516                                        |root: &mut #name| Some(&mut root.#field_ident),
2517                                    )
2518                                }
2519                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
2520    #name,
2521    std::sync::RwLock<#inner_ty>,
2522    &'a #name,
2523    &'a std::sync::RwLock<#inner_ty>,
2524    &'a mut #name,
2525    &'a mut std::sync::RwLock<#inner_ty>,
2526    impl Fn(&'a #name) -> Option<&'a std::sync::RwLock<#inner_ty>>,
2527    impl Fn(&'a mut #name) -> Option<&'a mut std::sync::RwLock<#inner_ty>>,
2528> {
2529                                    rust_key_paths::Kp::new(
2530                                        |root: &#name| root.#field_ident.as_ref(),
2531                                        |root: &mut #name| root.#field_ident.as_mut(),
2532                                    )
2533                                }
2534                            });
2535                        }
2536                        (WrapperKind::OptionRwLock, Some(inner_ty)) => {
2537                            let kp_unlocked_fn = format_ident!("{}_unlocked", field_ident);
2538                            tokens.extend(quote! {
2539                                #[inline(always)]
2540                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2541    #name,
2542    #ty,
2543    &'a #name,
2544    &'a #ty,
2545    &'a mut #name,
2546    &'a mut #ty,
2547    impl Fn(&'a #name) -> Option<&'a #ty>,
2548    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2549> {
2550                                    rust_key_paths::Kp::new(
2551                                        |root: &#name| Some(&root.#field_ident),
2552                                        |root: &mut #name| Some(&mut root.#field_ident),
2553                                    )
2554                                }
2555                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
2556    #name,
2557    parking_lot::RwLock<#inner_ty>,
2558    &'a #name,
2559    &'a parking_lot::RwLock<#inner_ty>,
2560    &'a mut #name,
2561    &'a mut parking_lot::RwLock<#inner_ty>,
2562    impl Fn(&'a #name) -> Option<&'a parking_lot::RwLock<#inner_ty>>,
2563    impl Fn(&'a mut #name) -> Option<&'a mut parking_lot::RwLock<#inner_ty>>,
2564> {
2565                                    rust_key_paths::Kp::new(
2566                                        |root: &#name| root.#field_ident.as_ref(),
2567                                        |root: &mut #name| root.#field_ident.as_mut(),
2568                                    )
2569                                }
2570                            });
2571                        }
2572                        (WrapperKind::Weak, Some(_inner_ty)) => {
2573                            // For Weak<T>, return keypath to container
2574                            tokens.extend(quote! {
2575                                #[inline(always)]
2576                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2577    #name,
2578    #ty,
2579    &'a #name,
2580    &'a #ty,
2581    &'a mut #name,
2582    &'a mut #ty,
2583    impl Fn(&'a #name) -> Option<&'a #ty>,
2584    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2585> {
2586                                    rust_key_paths::Kp::new(
2587                                        |root: &#name| Some(&root.#field_ident),
2588                                        |_root: &mut #name| None, // Weak doesn't support mutable access
2589                                    )
2590                                }
2591                            });
2592                        }
2593                        (WrapperKind::Atomic, None | Some(_)) => {
2594                            // For atomic types: return keypath to the atomic (user calls .load()/.store())
2595                            tokens.extend(quote! {
2596                                #[inline(always)]
2597                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2598    #name,
2599    #ty,
2600    &'a #name,
2601    &'a #ty,
2602    &'a mut #name,
2603    &'a mut #ty,
2604    impl Fn(&'a #name) -> Option<&'a #ty>,
2605    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2606> {
2607                                    rust_key_paths::Kp::new(
2608                                        |root: &#name| Some(&root.#field_ident),
2609                                        |root: &mut #name| Some(&mut root.#field_ident),
2610                                    )
2611                                }
2612                            });
2613                        }
2614                        (WrapperKind::OptionAtomic, Some(inner_ty)) => {
2615                            tokens.extend(quote! {
2616                                #[inline(always)]
2617                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2618    #name,
2619    #inner_ty,
2620    &'a #name,
2621    &'a #inner_ty,
2622    &'a mut #name,
2623    &'a mut #inner_ty,
2624    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
2625    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
2626> {
2627                                    rust_key_paths::Kp::new(
2628                                        |root: &#name| root.#field_ident.as_ref(),
2629                                        |root: &mut #name| root.#field_ident.as_mut(),
2630                                    )
2631                                }
2632                            });
2633                        }
2634                        (WrapperKind::String, None) => {
2635                            tokens.extend(quote! {
2636                                #[inline(always)]
2637                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2638    #name,
2639    #ty,
2640    &'a #name,
2641    &'a #ty,
2642    &'a mut #name,
2643    &'a mut #ty,
2644    impl Fn(&'a #name) -> Option<&'a #ty>,
2645    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2646> {
2647                                    rust_key_paths::Kp::new(
2648                                        |root: &#name| Some(&root.#field_ident),
2649                                        |root: &mut #name| Some(&mut root.#field_ident),
2650                                    )
2651                                }
2652                            });
2653                        }
2654                        (WrapperKind::OptionString, None) => {
2655                            tokens.extend(quote! {
2656                                #[inline(always)]
2657                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<#name, std::string::String, &'a #name, &'a std::string::String, &'a mut #name, &'a mut std::string::String, impl Fn(&'a #name) -> Option<&'a std::string::String>, impl Fn(&'a mut #name) -> Option<&'a mut std::string::String>,>  {
2658                                    rust_key_paths::Kp::new(
2659                                        |root: &#name| root.#field_ident.as_ref(),
2660                                        |root: &mut #name| root.#field_ident.as_mut(),
2661                                    )
2662                                }
2663                            });
2664                        }
2665                        (WrapperKind::Cell, Some(_inner_ty)) => {
2666                            tokens.extend(quote! {
2667                                #[inline(always)]
2668                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2669    #name,
2670    #ty,
2671    &'a #name,
2672    &'a #ty,
2673    &'a mut #name,
2674    &'a mut #ty,
2675    impl Fn(&'a #name) -> Option<&'a #ty>,
2676    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2677> {
2678                                    rust_key_paths::Kp::new(
2679                                        |root: &#name| Some(&root.#field_ident),
2680                                        |root: &mut #name| Some(&mut root.#field_ident),
2681                                    )
2682                                }
2683                            });
2684                        }
2685                        (WrapperKind::RefCell, Some(_inner_ty)) => {
2686                            tokens.extend(quote! {
2687                                #[inline(always)]
2688                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2689    #name,
2690    #ty,
2691    &'a #name,
2692    &'a #ty,
2693    &'a mut #name,
2694    &'a mut #ty,
2695    impl Fn(&'a #name) -> Option<&'a #ty>,
2696    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2697> {
2698                                    rust_key_paths::Kp::new(
2699                                        |root: &#name| Some(&root.#field_ident),
2700                                        |root: &mut #name| Some(&mut root.#field_ident),
2701                                    )
2702                                }
2703                            });
2704                        }
2705                        (WrapperKind::OnceCell, Some(inner_ty)) => {
2706                            // OnceLock/OnceCell: keypath to inner value; get = .get() -> Option<&T>, set = None
2707                            tokens.extend(quote! {
2708                                #[inline(always)]
2709                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2710    #name,
2711    #inner_ty,
2712    &'a #name,
2713    &'a #inner_ty,
2714    &'a mut #name,
2715    &'a mut #inner_ty,
2716    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
2717    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
2718> {
2719                                    rust_key_paths::Kp::new(
2720                                        |root: &#name| root.#field_ident.get(),
2721                                        |_root: &mut #name| None,
2722                                    )
2723                                }
2724                            });
2725                        }
2726                        (WrapperKind::Lazy, Some(inner_ty)) => {
2727                            // Lazy/LazyLock: keypath to inner value; get = .get() -> &T wrapped in Some, set = None
2728                            tokens.extend(quote! {
2729                                #[inline(always)]
2730                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2731    #name,
2732    #inner_ty,
2733    &'a #name,
2734    &'a #inner_ty,
2735    &'a mut #name,
2736    &'a mut #inner_ty,
2737    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
2738    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
2739> {
2740                                    rust_key_paths::Kp::new(
2741                                        |root: &#name| Some(root.#field_ident.get()),
2742                                        |_root: &mut #name| None,
2743                                    )
2744                                }
2745                            });
2746                        }
2747                        (WrapperKind::PhantomData, Some(_inner_ty)) => {
2748                            tokens.extend(quote! {
2749                                #[inline(always)]
2750                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2751    #name,
2752    #ty,
2753    &'a #name,
2754    &'a #ty,
2755    &'a mut #name,
2756    &'a mut #ty,
2757    impl Fn(&'a #name) -> Option<&'a #ty>,
2758    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2759> {
2760                                    rust_key_paths::Kp::new(
2761                                        |root: &#name| Some(&root.#field_ident),
2762                                        |root: &mut #name| Some(&mut root.#field_ident),
2763                                    )
2764                                }
2765                            });
2766                        }
2767                        (WrapperKind::Range, Some(_inner_ty)) => {
2768                            tokens.extend(quote! {
2769                                #[inline(always)]
2770                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2771    #name,
2772    #ty,
2773    &'a #name,
2774    &'a #ty,
2775    &'a mut #name,
2776    &'a mut #ty,
2777    impl Fn(&'a #name) -> Option<&'a #ty>,
2778    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2779> {
2780                                    rust_key_paths::Kp::new(
2781                                        |root: &#name| Some(&root.#field_ident),
2782                                        |root: &mut #name| Some(&mut root.#field_ident),
2783                                    )
2784                                }
2785                            });
2786                        }
2787                        (WrapperKind::OptionCell, Some(_inner_ty)) => {
2788                            tokens.extend(quote! {
2789                                #[inline(always)]
2790                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2791    #name,
2792    #ty,
2793    &'a #name,
2794    &'a #ty,
2795    &'a mut #name,
2796    &'a mut #ty,
2797    impl Fn(&'a #name) -> Option<&'a #ty>,
2798    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2799> {
2800                                    rust_key_paths::Kp::new(
2801                                        |root: &#name| Some(&root.#field_ident),
2802                                        |root: &mut #name| Some(&mut root.#field_ident),
2803                                    )
2804                                }
2805                            });
2806                        }
2807                        (WrapperKind::OptionRefCell, Some(inner_ty)) => {
2808                            // Option<RefCell<T>>: keypath to T via borrow()/borrow_mut(); get returns Option<Ref<V>> so caller holds guard (deref for &V)
2809                            tokens.extend(quote! {
2810                                #[inline(always)]
2811                                pub fn #kp_fn() -> rust_key_paths::KpOptionRefCellType<'_, #name, #inner_ty> {
2812                                    rust_key_paths::Kp::new(
2813                                        |root: &#name| root.#field_ident.as_ref().map(|r| r.borrow()),
2814                                        |root: &mut #name| root.#field_ident.as_ref().map(|r| r.borrow_mut()),
2815                                    )
2816                                }
2817                            });
2818                        }
2819                        (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
2820                            tokens.extend(quote! {
2821                                #[inline(always)]
2822                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2823    #name,
2824    #inner_ty,
2825    &'a #name,
2826    &'a #inner_ty,
2827    &'a mut #name,
2828    &'a mut #inner_ty,
2829    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
2830    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
2831> {
2832                                    rust_key_paths::Kp::new(
2833                                        |root: &#name| root.#field_ident.as_ref().and_then(|c| c.get()),
2834                                        |_root: &mut #name| None,
2835                                    )
2836                                }
2837                            });
2838                        }
2839                        (WrapperKind::OptionLazy, Some(inner_ty)) => {
2840                            tokens.extend(quote! {
2841                                #[inline(always)]
2842                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2843    #name,
2844    #inner_ty,
2845    &'a #name,
2846    &'a #inner_ty,
2847    &'a mut #name,
2848    &'a mut #inner_ty,
2849    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
2850    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
2851> {
2852                                    rust_key_paths::Kp::new(
2853                                        |root: &#name| root.#field_ident.as_ref().map(|c| c.get()),
2854                                        |_root: &mut #name| None,
2855                                    )
2856                                }
2857                            });
2858                        }
2859                        (WrapperKind::OptionPhantomData, Some(_inner_ty)) => {
2860                            tokens.extend(quote! {
2861                                #[inline(always)]
2862                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2863    #name,
2864    #ty,
2865    &'a #name,
2866    &'a #ty,
2867    &'a mut #name,
2868    &'a mut #ty,
2869    impl Fn(&'a #name) -> Option<&'a #ty>,
2870    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2871> {
2872                                    rust_key_paths::Kp::new(
2873                                        |root: &#name| Some(&root.#field_ident),
2874                                        |root: &mut #name| Some(&mut root.#field_ident),
2875                                    )
2876                                }
2877                            });
2878                        }
2879                        (WrapperKind::OptionRange, Some(_inner_ty)) => {
2880                            tokens.extend(quote! {
2881                                #[inline(always)]
2882                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2883    #name,
2884    #ty,
2885    &'a #name,
2886    &'a #ty,
2887    &'a mut #name,
2888    &'a mut #ty,
2889    impl Fn(&'a #name) -> Option<&'a #ty>,
2890    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2891> {
2892                                    rust_key_paths::Kp::new(
2893                                        |root: &#name| Some(&root.#field_ident),
2894                                        |root: &mut #name| Some(&mut root.#field_ident),
2895                                    )
2896                                }
2897                            });
2898                        }
2899                        (WrapperKind::Reference, Some(_inner_ty)) => {
2900                            // For reference types (&T, &str, &[T]): read-only, setter returns None
2901                            tokens.extend(quote! {
2902                                #[inline(always)]
2903                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2904    #name,
2905    #ty,
2906    &'a #name,
2907    &'a #ty,
2908    &'a mut #name,
2909    &'a mut #ty,
2910    impl Fn(&'a #name) -> Option<&'a #ty>,
2911    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2912> {
2913                                    rust_key_paths::Kp::new(
2914                                        |root: &#name| Some(&root.#field_ident),
2915                                        |_root: &mut #name| None, // references: read-only
2916                                    )
2917                                }
2918                            });
2919                        }
2920                        (WrapperKind::None, None) => {
2921                            // For basic types, direct access
2922                            tokens.extend(quote! {
2923                                #[inline(always)]
2924                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2925    #name,
2926    #ty,
2927    &'a #name,
2928    &'a #ty,
2929    &'a mut #name,
2930    &'a mut #ty,
2931    impl Fn(&'a #name) -> Option<&'a #ty>,
2932    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2933> {
2934                                    rust_key_paths::Kp::new(
2935                                        |root: &#name| Some(&root.#field_ident),
2936                                        |root: &mut #name| Some(&mut root.#field_ident),
2937                                    )
2938                                }
2939                            });
2940                        }
2941                        _ => {
2942                            // For unknown/complex nested types, return keypath to field itself
2943                            tokens.extend(quote! {
2944                                #[inline(always)]
2945                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
2946    #name,
2947    #ty,
2948    &'a #name,
2949    &'a #ty,
2950    &'a mut #name,
2951    &'a mut #ty,
2952    impl Fn(&'a #name) -> Option<&'a #ty>,
2953    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
2954> {
2955                            rust_key_paths::Kp::new(
2956                                |root: &#name| Some(&root.#field_ident),
2957                                |root: &mut #name| Some(&mut root.#field_ident),
2958                            )
2959                        }
2960                            });
2961                        }
2962                    }
2963                }
2964
2965                tokens
2966            }
2967            Fields::Unnamed(unnamed) => {
2968                let mut tokens = proc_macro2::TokenStream::new();
2969
2970                // Generate identity methods for the tuple struct
2971                tokens.extend(quote! {
2972                    /// Returns a generic identity keypath for this type
2973                    #[inline(always)]
2974                    pub fn identity_typed<'a, Root, MutRoot>() -> rust_key_paths::Kp<
2975                        #name,
2976                        #name,
2977                        Root,
2978                        Root,
2979                        MutRoot,
2980                        MutRoot,
2981                        fn(Root) -> Option<Root>,
2982                        fn(MutRoot) -> Option<MutRoot>,
2983                    >
2984                    where
2985                        Root: std::borrow::Borrow<#name>,
2986                        MutRoot: std::borrow::BorrowMut<#name>,
2987                    {
2988                        rust_key_paths::Kp::new(
2989                            |r: Root| Some(r),
2990                            |r: MutRoot| Some(r)
2991                        )
2992                    }
2993
2994                    /// Returns a simple identity keypath for this type
2995                    #[inline(always)]
2996                    pub fn identity<'a>() -> rust_key_paths::Kp<#name, #name, &'a #name, &'a #name, &'a mut #name, &'a mut #name, impl Fn(&'a #name) -> Option<&'a #name>, impl Fn(&'a mut #name) -> Option<&'a mut #name>,> {
2997                        rust_key_paths::Kp::new(
2998                            |r: &#name| Some(r),
2999                            |r: &mut #name| Some(r)
3000                        )
3001                    }
3002                });
3003
3004                for (idx, field) in unnamed.unnamed.iter().enumerate() {
3005                    let idx_lit = syn::Index::from(idx);
3006                    let ty = &field.ty;
3007                    // Centralized keypath method names for tuple fields – change here to adjust for all types
3008                    let kp_fn = format_ident!("f{}", idx);
3009                    let kp_at_fn = format_ident!("f{}_at", idx);
3010
3011                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
3012
3013                    match (kind, inner_ty.clone()) {
3014                        (WrapperKind::Option, Some(inner_ty)) => {
3015                            tokens.extend(quote! {
3016                                #[inline(always)]
3017                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3018    #name,
3019    #inner_ty,
3020    &'a #name,
3021    &'a #inner_ty,
3022    &'a mut #name,
3023    &'a mut #inner_ty,
3024    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3025    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3026> {
3027                                    rust_key_paths::Kp::new(
3028                                        |root: &#name| root.#idx_lit.as_ref(),
3029                                        |root: &mut #name| root.#idx_lit.as_mut(),
3030                                    )
3031                                }
3032                            });
3033                        }
3034                        (WrapperKind::OptionBox, Some(inner_ty)) => {
3035                            tokens.extend(quote! {
3036                                #[inline(always)]
3037                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3038    #name,
3039    #inner_ty,
3040    &'a #name,
3041    &'a #inner_ty,
3042    &'a mut #name,
3043    &'a mut #inner_ty,
3044    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3045    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3046> {
3047                                    rust_key_paths::Kp::new(
3048                                        |root: &#name| root.#idx_lit.as_deref(),
3049                                        |root: &mut #name| root.#idx_lit.as_deref_mut(),
3050                                    )
3051                                }
3052                            });
3053                        }
3054                        (WrapperKind::OptionRc, Some(inner_ty)) => {
3055                            tokens.extend(quote! {
3056                                #[inline(always)]
3057                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3058    #name,
3059    #inner_ty,
3060    &'a #name,
3061    &'a #inner_ty,
3062    &'a mut #name,
3063    &'a mut #inner_ty,
3064    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3065    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3066> {
3067                                    rust_key_paths::Kp::new(
3068                                        |root: &#name| root.#idx_lit.as_deref(),
3069                                        |root: &mut #name| root.#idx_lit.as_mut().and_then(std::rc::Rc::get_mut),
3070                                    )
3071                                }
3072                            });
3073                        }
3074                        (WrapperKind::OptionArc, Some(inner_ty)) => {
3075                            tokens.extend(quote! {
3076                                #[inline(always)]
3077                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3078    #name,
3079    #inner_ty,
3080    &'a #name,
3081    &'a #inner_ty,
3082    &'a mut #name,
3083    &'a mut #inner_ty,
3084    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3085    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3086> {
3087                                    rust_key_paths::Kp::new(
3088                                        |root: &#name| root.#idx_lit.as_deref(),
3089                                        |root: &mut #name| root.#idx_lit.as_mut().and_then(std::sync::Arc::get_mut),
3090                                    )
3091                                }
3092                            });
3093                        }
3094                        (WrapperKind::OptionHashMap, Some(inner_ty)) => {
3095                            if let Some((key_ty, _)) = extract_map_key_value_through_option(ty) {
3096                                let type_name = name.to_string();
3097                                let whole_fn = kp_fn.to_string();
3098                                let at_fn = kp_at_fn.to_string();
3099                                let whole_doc = format!(
3100                                    "Keypath to the whole optional `HashMap` (`{type_name}::{whole_fn}`). For a value at one key when the map is `Some`, use `{type_name}::{at_fn}(key)`."
3101                                );
3102                                let at_doc = format!(
3103                                    "Keyed access into the inner `HashMap` (`{type_name}::{at_fn}`). `get`/`get_mut` return `None` if the field is `None` or the key is missing. See also `{type_name}::{whole_fn}` for the full optional map."
3104                                );
3105                                tokens.extend(quote! {
3106                                    #[doc = #whole_doc]
3107                                    #[inline(always)]
3108                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3109    #name,
3110    #ty,
3111    &'a #name,
3112    &'a #ty,
3113    &'a mut #name,
3114    &'a mut #ty,
3115    impl Fn(&'a #name) -> Option<&'a #ty>,
3116    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3117> {
3118                                        rust_key_paths::Kp::new(
3119                                            |root: &#name| Some(&root.#idx_lit),
3120                                            |root: &mut #name| Some(&mut root.#idx_lit),
3121                                        )
3122                                    }
3123                                    #[doc = #at_doc]
3124                                    #[inline(always)]
3125                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3126                                    where
3127                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
3128                                    {
3129                                        let key2 = key.clone();
3130                                        rust_key_paths::Kp::new(
3131                                            Box::new(move |root: &#name| root.#idx_lit.as_ref().and_then(|m| m.get(&key))),
3132                                            Box::new(move |root: &mut #name| root.#idx_lit.as_mut().and_then(|m| m.get_mut(&key2))),
3133                                        )
3134                                    }
3135                                });
3136                            } else {
3137                                tokens.extend(quote! {
3138                                    #[inline(always)]
3139                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3140    #name,
3141    #ty,
3142    &'a #name,
3143    &'a #ty,
3144    &'a mut #name,
3145    &'a mut #ty,
3146    impl Fn(&'a #name) -> Option<&'a #ty>,
3147    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3148> {
3149                                        rust_key_paths::Kp::new(
3150                                            |root: &#name| Some(&root.#idx_lit),
3151                                            |root: &mut #name| Some(&mut root.#idx_lit),
3152                                        )
3153                                    }
3154                                });
3155                            }
3156                        }
3157                        (WrapperKind::OptionBTreeMap, Some(inner_ty)) => {
3158                            if let Some((key_ty, _)) = extract_map_key_value_through_option(ty) {
3159                                let type_name = name.to_string();
3160                                let whole_fn = kp_fn.to_string();
3161                                let at_fn = kp_at_fn.to_string();
3162                                let whole_doc = format!(
3163                                    "Keypath to the whole optional `BTreeMap` (`{type_name}::{whole_fn}`). For a value at one key when the map is `Some`, use `{type_name}::{at_fn}(key)`."
3164                                );
3165                                let at_doc = format!(
3166                                    "Keyed access into the inner `BTreeMap` (`{type_name}::{at_fn}`). `get`/`get_mut` return `None` if the field is `None` or the key is missing. See also `{type_name}::{whole_fn}` for the full optional map."
3167                                );
3168                                tokens.extend(quote! {
3169                                    #[doc = #whole_doc]
3170                                    #[inline(always)]
3171                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3172    #name,
3173    #ty,
3174    &'a #name,
3175    &'a #ty,
3176    &'a mut #name,
3177    &'a mut #ty,
3178    impl Fn(&'a #name) -> Option<&'a #ty>,
3179    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3180> {
3181                                        rust_key_paths::Kp::new(
3182                                            |root: &#name| Some(&root.#idx_lit),
3183                                            |root: &mut #name| Some(&mut root.#idx_lit),
3184                                        )
3185                                    }
3186                                    #[doc = #at_doc]
3187                                    #[inline(always)]
3188                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3189                                    where
3190                                        #key_ty: Clone + Ord + 'static,
3191                                    {
3192                                        let key2 = key.clone();
3193                                        rust_key_paths::Kp::new(
3194                                            Box::new(move |root: &#name| root.#idx_lit.as_ref().and_then(|m| m.get(&key))),
3195                                            Box::new(move |root: &mut #name| root.#idx_lit.as_mut().and_then(|m| m.get_mut(&key2))),
3196                                        )
3197                                    }
3198                                });
3199                            } else {
3200                                tokens.extend(quote! {
3201                                    #[inline(always)]
3202                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3203    #name,
3204    #ty,
3205    &'a #name,
3206    &'a #ty,
3207    &'a mut #name,
3208    &'a mut #ty,
3209    impl Fn(&'a #name) -> Option<&'a #ty>,
3210    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3211> {
3212                                        rust_key_paths::Kp::new(
3213                                            |root: &#name| Some(&root.#idx_lit),
3214                                            |root: &mut #name| Some(&mut root.#idx_lit),
3215                                        )
3216                                    }
3217                                });
3218                            }
3219                        }
3220                        (WrapperKind::OptionHashSet, Some(inner_ty)) => {
3221                            tokens.extend(quote! {
3222                                #[inline(always)]
3223                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3224    #name,
3225    #ty,
3226    &'a #name,
3227    &'a #ty,
3228    &'a mut #name,
3229    &'a mut #ty,
3230    impl Fn(&'a #name) -> Option<&'a #ty>,
3231    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3232> {
3233                                    rust_key_paths::Kp::new(
3234                                        |root: &#name| Some(&root.#idx_lit),
3235                                        |root: &mut #name| Some(&mut root.#idx_lit),
3236                                    )
3237                                }
3238
3239                                /// _at: check if element exists and get reference.
3240                                /// HashSet does not allow mutable element access (would break hash invariant).
3241                                #[inline(always)]
3242                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3243                                where
3244                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
3245                                {
3246                                    rust_key_paths::Kp::new(
3247                                        Box::new(move |root: &#name| root.#idx_lit.as_ref().and_then(|s| s.get(&key))),
3248                                        Box::new(move |_root: &mut #name| None),
3249                                    )
3250                                }
3251                            });
3252                        }
3253                        (WrapperKind::OptionBTreeSet, Some(inner_ty)) => {
3254                            tokens.extend(quote! {
3255                                #[inline(always)]
3256                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3257    #name,
3258    #ty,
3259    &'a #name,
3260    &'a #ty,
3261    &'a mut #name,
3262    &'a mut #ty,
3263    impl Fn(&'a #name) -> Option<&'a #ty>,
3264    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3265> {
3266                                    rust_key_paths::Kp::new(
3267                                        |root: &#name| Some(&root.#idx_lit),
3268                                        |root: &mut #name| Some(&mut root.#idx_lit),
3269                                    )
3270                                }
3271
3272                                /// _at: check if element exists and get reference.
3273                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
3274                                #[inline(always)]
3275                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3276                                where
3277                                    #inner_ty: Clone + Ord + 'static,
3278                                {
3279                                    rust_key_paths::Kp::new(
3280                                        Box::new(move |root: &#name| root.#idx_lit.as_ref().and_then(|s| s.get(&key))),
3281                                        Box::new(move |_root: &mut #name| None),
3282                                    )
3283                                }
3284                            });
3285                        }
3286                        (WrapperKind::OptionVec, Some(inner_ty)) => {
3287                            tokens.extend(quote! {
3288                                #[inline(always)]
3289                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3290    #name,
3291    #ty,
3292    &'a #name,
3293    &'a #ty,
3294    &'a mut #name,
3295    &'a mut #ty,
3296    impl Fn(&'a #name) -> Option<&'a #ty>,
3297    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3298> {
3299                                    rust_key_paths::Kp::new(
3300                                        |root: &#name| Some(&root.#idx_lit),
3301                                        |root: &mut #name| Some(&mut root.#idx_lit),
3302                                    )
3303                                }
3304                                #[inline(always)]
3305                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
3306                                    rust_key_paths::Kp::new(
3307                                        Box::new(move |root: &#name| root.#idx_lit.as_ref().and_then(|v| v.get(index))),
3308                                        Box::new(move |root: &mut #name| root.#idx_lit.as_mut().and_then(|v| v.get_mut(index))),
3309                                    )
3310                                }
3311                            });
3312                        }
3313                        (WrapperKind::OptionVecDeque, Some(inner_ty)) => {
3314                            tokens.extend(quote! {
3315                                #[inline(always)]
3316                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3317    #name,
3318    #ty,
3319    &'a #name,
3320    &'a #ty,
3321    &'a mut #name,
3322    &'a mut #ty,
3323    impl Fn(&'a #name) -> Option<&'a #ty>,
3324    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3325> {
3326                                    rust_key_paths::Kp::new(
3327                                        |root: &#name| Some(&root.#idx_lit),
3328                                        |root: &mut #name| Some(&mut root.#idx_lit),
3329                                    )
3330                                }
3331                                #[inline(always)]
3332                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
3333                                    rust_key_paths::Kp::new(
3334                                        Box::new(move |root: &#name| root.#idx_lit.as_ref().and_then(|v| v.get(index))),
3335                                        Box::new(move |root: &mut #name| root.#idx_lit.as_mut().and_then(|v| v.get_mut(index))),
3336                                    )
3337                                }
3338                            });
3339                        }
3340                        (WrapperKind::OptionLinkedList, Some(_inner_ty))
3341                        | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
3342                        | (WrapperKind::OptionResult, Some(_inner_ty)) => {
3343                            tokens.extend(quote! {
3344                                #[inline(always)]
3345                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3346    #name,
3347    #ty,
3348    &'a #name,
3349    &'a #ty,
3350    &'a mut #name,
3351    &'a mut #ty,
3352    impl Fn(&'a #name) -> Option<&'a #ty>,
3353    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3354> {
3355                                    rust_key_paths::Kp::new(
3356                                        |root: &#name| Some(&root.#idx_lit),
3357                                        |root: &mut #name| Some(&mut root.#idx_lit),
3358                                    )
3359                                }
3360                            });
3361                        }
3362                        (WrapperKind::Vec, Some(inner_ty)) => {
3363                            tokens.extend(quote! {
3364                                #[inline(always)]
3365                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3366    #name,
3367    #ty,
3368    &'a #name,
3369    &'a #ty,
3370    &'a mut #name,
3371    &'a mut #ty,
3372    impl Fn(&'a #name) -> Option<&'a #ty>,
3373    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3374> {
3375                                    rust_key_paths::Kp::new(
3376                                        |root: &#name| Some(&root.#idx_lit),
3377                                        |root: &mut #name| Some(&mut root.#idx_lit),
3378                                    )
3379                                }
3380                                #[inline(always)]
3381                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
3382                                    rust_key_paths::Kp::new(
3383                                        Box::new(move |root: &#name| root.#idx_lit.get(index)),
3384                                        Box::new(move |root: &mut #name| root.#idx_lit.get_mut(index)),
3385                                    )
3386                                }
3387                            });
3388                        }
3389                        (WrapperKind::HashMap, Some(inner_ty)) => {
3390                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
3391                                tokens.extend(quote! {
3392                                    #[inline(always)]
3393                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3394    #name,
3395    #ty,
3396    &'a #name,
3397    &'a #ty,
3398    &'a mut #name,
3399    &'a mut #ty,
3400    impl Fn(&'a #name) -> Option<&'a #ty>,
3401    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3402> {
3403                                        rust_key_paths::Kp::new(
3404                                            |root: &#name| Some(&root.#idx_lit),
3405                                            |root: &mut #name| Some(&mut root.#idx_lit),
3406                                        )
3407                                    }
3408                                    #[inline(always)]
3409                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3410                                    where
3411                                        #key_ty: Clone + std::hash::Hash + Eq + 'static,
3412                                    {
3413                                        let key2 = key.clone();
3414                                        rust_key_paths::Kp::new(
3415                                            Box::new(move |root: &#name| root.#idx_lit.get(&key)),
3416                                            Box::new(move |root: &mut #name| root.#idx_lit.get_mut(&key2)),
3417                                        )
3418                                    }
3419                                });
3420                            } else {
3421                                tokens.extend(quote! {
3422                                    #[inline(always)]
3423                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3424    #name,
3425    #ty,
3426    &'a #name,
3427    &'a #ty,
3428    &'a mut #name,
3429    &'a mut #ty,
3430    impl Fn(&'a #name) -> Option<&'a #ty>,
3431    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3432> {
3433                                        rust_key_paths::Kp::new(
3434                                            |root: &#name| Some(&root.#idx_lit),
3435                                            |root: &mut #name| Some(&mut root.#idx_lit),
3436                                        )
3437                                    }
3438                                });
3439                            }
3440                        }
3441                        (WrapperKind::BTreeMap, Some(inner_ty))
3442                        | (WrapperKind::BTreeMapOption, Some(inner_ty)) => {
3443                            if let Some((key_ty, _)) = extract_map_key_value(ty) {
3444                                tokens.extend(quote! {
3445                                    #[inline(always)]
3446                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3447    #name,
3448    #ty,
3449    &'a #name,
3450    &'a #ty,
3451    &'a mut #name,
3452    &'a mut #ty,
3453    impl Fn(&'a #name) -> Option<&'a #ty>,
3454    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3455> {
3456                                        rust_key_paths::Kp::new(
3457                                            |root: &#name| Some(&root.#idx_lit),
3458                                            |root: &mut #name| Some(&mut root.#idx_lit),
3459                                        )
3460                                    }
3461                                    #[inline(always)]
3462                                    pub fn #kp_at_fn(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3463                                    where
3464                                        #key_ty: Clone + Ord + 'static,
3465                                    {
3466                                        let key2 = key.clone();
3467                                        rust_key_paths::Kp::new(
3468                                            Box::new(move |root: &#name| root.#idx_lit.get(&key)),
3469                                            Box::new(move |root: &mut #name| root.#idx_lit.get_mut(&key2)),
3470                                        )
3471                                    }
3472                                });
3473                            } else {
3474                                tokens.extend(quote! {
3475                                    #[inline(always)]
3476                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3477    #name,
3478    #ty,
3479    &'a #name,
3480    &'a #ty,
3481    &'a mut #name,
3482    &'a mut #ty,
3483    impl Fn(&'a #name) -> Option<&'a #ty>,
3484    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3485> {
3486                                        rust_key_paths::Kp::new(
3487                                            |root: &#name| Some(&root.#idx_lit),
3488                                            |root: &mut #name| Some(&mut root.#idx_lit),
3489                                        )
3490                                    }
3491                                });
3492                            }
3493                        }
3494                        (WrapperKind::Box, Some(inner_ty)) => {
3495                            // Box: deref to inner (returns &T / &mut T)
3496                            tokens.extend(quote! {
3497                                #[inline(always)]
3498                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3499    #name,
3500    #inner_ty,
3501    &'a #name,
3502    &'a #inner_ty,
3503    &'a mut #name,
3504    &'a mut #inner_ty,
3505    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3506    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3507> {
3508                                    rust_key_paths::Kp::new(
3509                                        |root: &#name| Some(&*root.#idx_lit),
3510                                        |root: &mut #name| Some(&mut *root.#idx_lit),
3511                                    )
3512                                }
3513                            });
3514                        }
3515                        (WrapperKind::BoxOption, Some(inner_ty)) => {
3516                            tokens.extend(quote! {
3517                                #[inline(always)]
3518                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3519    #name,
3520    #inner_ty,
3521    &'a #name,
3522    &'a #inner_ty,
3523    &'a mut #name,
3524    &'a mut #inner_ty,
3525    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3526    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3527> {
3528                                    rust_key_paths::Kp::new(
3529                                        |root: &#name| (&*root.#idx_lit).as_ref(),
3530                                        |root: &mut #name| (&mut *root.#idx_lit).as_mut(),
3531                                    )
3532                                }
3533                            });
3534                        }
3535                        (WrapperKind::RcOption, Some(inner_ty)) => {
3536                            tokens.extend(quote! {
3537                                #[inline(always)]
3538                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3539    #name,
3540    #inner_ty,
3541    &'a #name,
3542    &'a #inner_ty,
3543    &'a mut #name,
3544    &'a mut #inner_ty,
3545    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3546    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3547> {
3548                                    rust_key_paths::Kp::new(
3549                                        |root: &#name| (&*root.#idx_lit).as_ref(),
3550                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#idx_lit).and_then(std::option::Option::as_mut),
3551                                    )
3552                                }
3553                            });
3554                        }
3555                        (WrapperKind::ArcOption, Some(inner_ty)) => {
3556                            tokens.extend(quote! {
3557                                #[inline(always)]
3558                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3559    #name,
3560    #inner_ty,
3561    &'a #name,
3562    &'a #inner_ty,
3563    &'a mut #name,
3564    &'a mut #inner_ty,
3565    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3566    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3567> {
3568                                    rust_key_paths::Kp::new(
3569                                        |root: &#name| (&*root.#idx_lit).as_ref(),
3570                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#idx_lit).and_then(std::option::Option::as_mut),
3571                                    )
3572                                }
3573                            });
3574                        }
3575                        (WrapperKind::Pin, Some(inner_ty)) => {
3576                            let kp_inner_fn = format_ident!("{}_inner", kp_fn);
3577                            tokens.extend(quote! {
3578                                #[inline(always)]
3579                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3580    #name,
3581    #ty,
3582    &'a #name,
3583    &'a #ty,
3584    &'a mut #name,
3585    &'a mut #ty,
3586    impl Fn(&'a #name) -> Option<&'a #ty>,
3587    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3588> {
3589                                    rust_key_paths::Kp::new(
3590                                        |root: &#name| Some(&root.#idx_lit),
3591                                        |root: &mut #name| Some(&mut root.#idx_lit),
3592                                    )
3593                                }
3594                                #[inline(always)]
3595                                pub fn #kp_inner_fn<'a>() -> rust_key_paths::Kp<
3596    #name,
3597    #inner_ty,
3598    &'a #name,
3599    &'a #inner_ty,
3600    &'a mut #name,
3601    &'a mut #inner_ty,
3602    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3603    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3604>
3605                                where #inner_ty: std::marker::Unpin
3606                                {
3607                                    rust_key_paths::Kp::new(
3608                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#idx_lit).get_ref()),
3609                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#idx_lit).get_mut()),
3610                                    )
3611                                }
3612                            });
3613                        }
3614                        (WrapperKind::PinBox, Some(inner_ty)) => {
3615                            let kp_inner_fn = format_ident!("{}_inner", kp_fn);
3616                            tokens.extend(quote! {
3617                                #[inline(always)]
3618                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3619    #name,
3620    #ty,
3621    &'a #name,
3622    &'a #ty,
3623    &'a mut #name,
3624    &'a mut #ty,
3625    impl Fn(&'a #name) -> Option<&'a #ty>,
3626    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3627> {
3628                                    rust_key_paths::Kp::new(
3629                                        |root: &#name| Some(&root.#idx_lit),
3630                                        |root: &mut #name| Some(&mut root.#idx_lit),
3631                                    )
3632                                }
3633                                #[inline(always)]
3634                                pub fn #kp_inner_fn<'a>() -> rust_key_paths::Kp<
3635    #name,
3636    #inner_ty,
3637    &'a #name,
3638    &'a #inner_ty,
3639    &'a mut #name,
3640    &'a mut #inner_ty,
3641    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3642    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3643>
3644                                where #inner_ty: std::marker::Unpin
3645                                {
3646                                    rust_key_paths::Kp::new(
3647                                        |root: &#name| Some(std::pin::Pin::as_ref(&root.#idx_lit).get_ref()),
3648                                        |root: &mut #name| Some(std::pin::Pin::as_mut(&mut root.#idx_lit).get_mut()),
3649                                    )
3650                                }
3651                            });
3652                        }
3653                        (WrapperKind::Rc, Some(inner_ty)) => {
3654                            tokens.extend(quote! {
3655                                #[inline(always)]
3656                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3657    #name,
3658    #inner_ty,
3659    &'a #name,
3660    &'a #inner_ty,
3661    &'a mut #name,
3662    &'a mut #inner_ty,
3663    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3664    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3665> {
3666                                    rust_key_paths::Kp::new(
3667                                        |root: &#name| Some(root.#idx_lit.as_ref()),
3668                                        |root: &mut #name| std::rc::Rc::get_mut(&mut root.#idx_lit),
3669                                    )
3670                                }
3671                            });
3672                        }
3673                        (WrapperKind::Arc, Some(inner_ty)) => {
3674                            tokens.extend(quote! {
3675                                #[inline(always)]
3676                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3677    #name,
3678    #inner_ty,
3679    &'a #name,
3680    &'a #inner_ty,
3681    &'a mut #name,
3682    &'a mut #inner_ty,
3683    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3684    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3685> {
3686                                    rust_key_paths::Kp::new(
3687                                        |root: &#name| Some(root.#idx_lit.as_ref()),
3688                                        |root: &mut #name| std::sync::Arc::get_mut(&mut root.#idx_lit),
3689                                    )
3690                                }
3691                            });
3692                        }
3693
3694                        (WrapperKind::Cow, Some(inner_ty)) => {
3695                            tokens.extend(quote! {
3696                                #[inline(always)]
3697                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3698    #name,
3699    #inner_ty,
3700    &'a #name,
3701    &'a #inner_ty,
3702    &'a mut #name,
3703    &'a mut #inner_ty,
3704    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3705    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3706> {
3707                                    rust_key_paths::Kp::new(
3708                                        |root: &#name| Some(root.#idx_lit.as_ref()),
3709                                        |root: &mut #name| Some(root.#idx_lit.to_mut()),
3710                                    )
3711                                }
3712                            });
3713                        }
3714
3715                        (WrapperKind::OptionCow, Some(inner_ty)) => {
3716                            tokens.extend(quote! {
3717                                #[inline(always)]
3718                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3719    #name,
3720    #inner_ty,
3721    &'a #name,
3722    &'a #inner_ty,
3723    &'a mut #name,
3724    &'a mut #inner_ty,
3725    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3726    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3727> {
3728                                    rust_key_paths::Kp::new(
3729                                        |root: &#name| root.#idx_lit.as_ref().map(|c| c.as_ref()),
3730                                        |root: &mut #name| root.#idx_lit.as_mut().map(|c| c.to_mut()),
3731                                    )
3732                                }
3733                            });
3734                        }
3735                        (WrapperKind::OptionTagged, Some(inner_ty)) => {
3736                            tokens.extend(quote! {
3737                                #[inline(always)]
3738                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3739    #name,
3740    #inner_ty,
3741    &'a #name,
3742    &'a #inner_ty,
3743    &'a mut #name,
3744    &'a mut #inner_ty,
3745    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3746    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3747> {
3748                                    rust_key_paths::Kp::new(
3749                                        |root: &#name| root.#idx_lit.as_ref().map(|t| std::ops::Deref::deref(t)),
3750                                        |root: &mut #name| root.#idx_lit.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
3751                                    )
3752                                }
3753                            });
3754                        }
3755                        (WrapperKind::OptionReference, Some(inner_ty)) => {
3756                            tokens.extend(quote! {
3757                                #[inline(always)]
3758                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3759    #name,
3760    #inner_ty,
3761    &'a #name,
3762    &'a #inner_ty,
3763    &'a mut #name,
3764    &'a mut #inner_ty,
3765    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3766    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3767> {
3768                                    rust_key_paths::Kp::new(
3769                                        |root: &#name| root.#idx_lit.as_ref(),
3770                                        |_root: &mut #name| None,
3771                                    )
3772                                }
3773                            });
3774                        }
3775                        (WrapperKind::HashSet, Some(inner_ty))
3776                        | (WrapperKind::HashSetOption, Some(inner_ty)) => {
3777                            let kp_at_fn = format_ident!("f{}_at", idx);
3778
3779                            tokens.extend(quote! {
3780                                #[inline(always)]
3781                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3782    #name,
3783    #ty,
3784    &'a #name,
3785    &'a #ty,
3786    &'a mut #name,
3787    &'a mut #ty,
3788    impl Fn(&'a #name) -> Option<&'a #ty>,
3789    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3790> {
3791                                    rust_key_paths::Kp::new(
3792                                        |root: &#name| Some(&root.#idx_lit),
3793                                        |root: &mut #name| Some(&mut root.#idx_lit),
3794                                    )
3795                                }
3796
3797                                /// _at: check if element exists and get reference.
3798                                /// HashSet does not allow mutable element access (would break hash invariant).
3799                                #[inline(always)]
3800                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3801                                where
3802                                    #inner_ty: Clone + std::hash::Hash + Eq + 'static,
3803                                {
3804                                    rust_key_paths::Kp::new(
3805                                        Box::new(move |root: &#name| root.#idx_lit.get(&key)),
3806                                        Box::new(move |_root: &mut #name| None),
3807                                    )
3808                                }
3809                            });
3810                        }
3811                        (WrapperKind::BTreeSet, Some(inner_ty))
3812                        | (WrapperKind::BTreeSetOption, Some(inner_ty)) => {
3813                            let kp_at_fn = format_ident!("f{}_at", idx);
3814
3815                            tokens.extend(quote! {
3816                                #[inline(always)]
3817                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3818    #name,
3819    #ty,
3820    &'a #name,
3821    &'a #ty,
3822    &'a mut #name,
3823    &'a mut #ty,
3824    impl Fn(&'a #name) -> Option<&'a #ty>,
3825    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3826> {
3827                                    rust_key_paths::Kp::new(
3828                                        |root: &#name| Some(&root.#idx_lit),
3829                                        |root: &mut #name| Some(&mut root.#idx_lit),
3830                                    )
3831                                }
3832
3833                                /// _at: check if element exists and get reference.
3834                                /// BTreeSet does not allow mutable element access (would break ordering invariant).
3835                                #[inline(always)]
3836                                pub fn #kp_at_fn(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
3837                                where
3838                                    #inner_ty: Clone + Ord + 'static,
3839                                {
3840                                    rust_key_paths::Kp::new(
3841                                        Box::new(move |root: &#name| root.#idx_lit.get(&key)),
3842                                        Box::new(move |_root: &mut #name| None),
3843                                    )
3844                                }
3845                            });
3846                        }
3847                        (WrapperKind::VecDeque, Some(inner_ty))
3848                        | (WrapperKind::VecDequeOption, Some(inner_ty)) => {
3849                            tokens.extend(quote! {
3850                                #[inline(always)]
3851                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3852    #name,
3853    #ty,
3854    &'a #name,
3855    &'a #ty,
3856    &'a mut #name,
3857    &'a mut #ty,
3858    impl Fn(&'a #name) -> Option<&'a #ty>,
3859    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3860> {
3861                                    rust_key_paths::Kp::new(
3862                                        |root: &#name| Some(&root.#idx_lit),
3863                                        |root: &mut #name| Some(&mut root.#idx_lit),
3864                                    )
3865                                }
3866                                #[inline(always)]
3867                                pub fn #kp_at_fn(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
3868                                    rust_key_paths::Kp::new(
3869                                        Box::new(move |root: &#name| root.#idx_lit.get(index)),
3870                                        Box::new(move |root: &mut #name| root.#idx_lit.get_mut(index)),
3871                                    )
3872                                }
3873                            });
3874                        }
3875                        (WrapperKind::LinkedList, Some(_inner_ty))
3876                        | (WrapperKind::LinkedListOption, Some(_inner_ty)) => {
3877                            tokens.extend(quote! {
3878                                #[inline(always)]
3879                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3880    #name,
3881    #ty,
3882    &'a #name,
3883    &'a #ty,
3884    &'a mut #name,
3885    &'a mut #ty,
3886    impl Fn(&'a #name) -> Option<&'a #ty>,
3887    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3888> {
3889                                    rust_key_paths::Kp::new(
3890                                        |root: &#name| Some(&root.#idx_lit),
3891                                        |root: &mut #name| Some(&mut root.#idx_lit),
3892                                    )
3893                                }
3894                            });
3895                        }
3896                        (WrapperKind::BinaryHeap, Some(_inner_ty))
3897                        | (WrapperKind::BinaryHeapOption, Some(_inner_ty)) => {
3898                            tokens.extend(quote! {
3899                                #[inline(always)]
3900                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3901    #name,
3902    #ty,
3903    &'a #name,
3904    &'a #ty,
3905    &'a mut #name,
3906    &'a mut #ty,
3907    impl Fn(&'a #name) -> Option<&'a #ty>,
3908    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3909> {
3910                                    rust_key_paths::Kp::new(
3911                                        |root: &#name| Some(&root.#idx_lit),
3912                                        |root: &mut #name| Some(&mut root.#idx_lit),
3913                                    )
3914                                }
3915                            });
3916                        }
3917                        (WrapperKind::Result, Some(inner_ty)) => {
3918                            tokens.extend(quote! {
3919                                #[inline(always)]
3920                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3921    #name,
3922    #inner_ty,
3923    &'a #name,
3924    &'a #inner_ty,
3925    &'a mut #name,
3926    &'a mut #inner_ty,
3927    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
3928    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
3929> {
3930                                    rust_key_paths::Kp::new(
3931                                        |root: &#name| root.#idx_lit.as_ref().ok(),
3932                                        |root: &mut #name| root.#idx_lit.as_mut().ok(),
3933                                    )
3934                                }
3935                            });
3936                        }
3937                        (WrapperKind::Mutex, Some(_inner_ty))
3938                        | (WrapperKind::StdMutex, Some(_inner_ty)) => {
3939                            tokens.extend(quote! {
3940                                #[inline(always)]
3941                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3942    #name,
3943    #ty,
3944    &'a #name,
3945    &'a #ty,
3946    &'a mut #name,
3947    &'a mut #ty,
3948    impl Fn(&'a #name) -> Option<&'a #ty>,
3949    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3950> {
3951                                    rust_key_paths::Kp::new(
3952                                        |root: &#name| Some(&root.#idx_lit),
3953                                        |root: &mut #name| Some(&mut root.#idx_lit),
3954                                    )
3955                                }
3956                            });
3957                        }
3958                        (WrapperKind::RwLock, Some(_inner_ty))
3959                        | (WrapperKind::StdRwLock, Some(_inner_ty)) => {
3960                            tokens.extend(quote! {
3961                                #[inline(always)]
3962                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
3963    #name,
3964    #ty,
3965    &'a #name,
3966    &'a #ty,
3967    &'a mut #name,
3968    &'a mut #ty,
3969    impl Fn(&'a #name) -> Option<&'a #ty>,
3970    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3971> {
3972                                    rust_key_paths::Kp::new(
3973                                        |root: &#name| Some(&root.#idx_lit),
3974                                        |root: &mut #name| Some(&mut root.#idx_lit),
3975                                    )
3976                                }
3977                            });
3978                        }
3979                        (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
3980                            let kp_async_fn = format_ident!("f{}_kp", idx);
3981                            tokens.extend(quote! {
3982                                #[inline(always)]
3983                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
3984    #name,
3985    #ty,
3986    &'a #name,
3987    &'a #ty,
3988    &'a mut #name,
3989    &'a mut #ty,
3990    impl Fn(&'a #name) -> Option<&'a #ty>,
3991    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
3992> {
3993                                    rust_key_paths::Kp::new(
3994                                        |root: &#name| Some(&root.#idx_lit),
3995                                        |root: &mut #name| Some(&mut root.#idx_lit),
3996                                    )
3997                                }
3998                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #ty, #inner_ty> {
3999                                    rust_key_paths::async_lock::AsyncLockKp::new(
4000                                        rust_key_paths::Kp::new(
4001                                            |root: &#name| Some(&root.#idx_lit),
4002                                            |root: &mut #name| Some(&mut root.#idx_lit),
4003                                        ),
4004                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
4005                                        rust_key_paths::Kp::new(
4006                                            |v: &#inner_ty| Some(v),
4007                                            |v: &mut #inner_ty| Some(v),
4008                                        ),
4009                                    )
4010                                }
4011                            });
4012                        }
4013                        (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
4014                            let kp_async_fn = format_ident!("f{}_kp", idx);
4015                            tokens.extend(quote! {
4016                                #[inline(always)]
4017                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
4018    #name,
4019    #ty,
4020    &'a #name,
4021    &'a #ty,
4022    &'a mut #name,
4023    &'a mut #ty,
4024    impl Fn(&'a #name) -> Option<&'a #ty>,
4025    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4026> {
4027                                    rust_key_paths::Kp::new(
4028                                        |root: &#name| Some(&root.#idx_lit),
4029                                        |root: &mut #name| Some(&mut root.#idx_lit),
4030                                    )
4031                                }
4032                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #ty, #inner_ty> {
4033                                    rust_key_paths::async_lock::AsyncLockKp::new(
4034                                        rust_key_paths::Kp::new(
4035                                            |root: &#name| Some(&root.#idx_lit),
4036                                            |root: &mut #name| Some(&mut root.#idx_lit),
4037                                        ),
4038                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
4039                                        rust_key_paths::Kp::new(
4040                                            |v: &#inner_ty| Some(v),
4041                                            |v: &mut #inner_ty| Some(v),
4042                                        ),
4043                                    )
4044                                }
4045                            });
4046                        }
4047                        (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
4048                            let kp_async_fn = format_ident!("f{}_kp", idx);
4049                            tokens.extend(quote! {
4050                                #[inline(always)]
4051                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
4052    #name,
4053    #ty,
4054    &'a #name,
4055    &'a #ty,
4056    &'a mut #name,
4057    &'a mut #ty,
4058    impl Fn(&'a #name) -> Option<&'a #ty>,
4059    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4060> {
4061                                    rust_key_paths::Kp::new(
4062                                        |root: &#name| Some(&root.#idx_lit),
4063                                        |root: &mut #name| Some(&mut root.#idx_lit),
4064                                    )
4065                                }
4066                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
4067                                    rust_key_paths::async_lock::AsyncLockKp::new(
4068                                        rust_key_paths::Kp::new(
4069                                            |root: &#name| root.#idx_lit.as_ref(),
4070                                            |root: &mut #name| root.#idx_lit.as_mut(),
4071                                        ),
4072                                        rust_key_paths::async_lock::TokioMutexAccess::new(),
4073                                        rust_key_paths::Kp::new(
4074                                            |v: &#inner_ty| Some(v),
4075                                            |v: &mut #inner_ty| Some(v),
4076                                        ),
4077                                    )
4078                                }
4079                            });
4080                        }
4081                        (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
4082                            let kp_async_fn = format_ident!("f{}_kp", idx);
4083                            tokens.extend(quote! {
4084                                #[inline(always)]
4085                                    pub fn #kp_async_fn<'a>() -> rust_key_paths::Kp<
4086    #name,
4087    #ty,
4088    &'a #name,
4089    &'a #ty,
4090    &'a mut #name,
4091    &'a mut #ty,
4092    impl Fn(&'a #name) -> Option<&'a #ty>,
4093    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4094> {
4095                                    rust_key_paths::Kp::new(
4096                                        |root: &#name| Some(&root.#idx_lit),
4097                                        |root: &mut #name| Some(&mut root.#idx_lit),
4098                                    )
4099                                }
4100                                pub fn #kp_fn() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
4101                                    rust_key_paths::async_lock::AsyncLockKp::new(
4102                                        rust_key_paths::Kp::new(
4103                                            |root: &#name| root.#idx_lit.as_ref(),
4104                                            |root: &mut #name| root.#idx_lit.as_mut(),
4105                                        ),
4106                                        rust_key_paths::async_lock::TokioRwLockAccess::new(),
4107                                        rust_key_paths::Kp::new(
4108                                            |v: &#inner_ty| Some(v),
4109                                            |v: &mut #inner_ty| Some(v),
4110                                        ),
4111                                    )
4112                                }
4113                            });
4114                        }
4115                        (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
4116                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4117                            tokens.extend(quote! {
4118                                #[inline(always)]
4119                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4120    #name,
4121    #ty,
4122    &'a #name,
4123    &'a #ty,
4124    &'a mut #name,
4125    &'a mut #ty,
4126    impl Fn(&'a #name) -> Option<&'a #ty>,
4127    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4128> {
4129                                    rust_key_paths::Kp::new(
4130                                        |root: &#name| Some(&root.#idx_lit),
4131                                        |root: &mut #name| Some(&mut root.#idx_lit),
4132                                    )
4133                                }
4134                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, &'a #name, &'a std::sync::Arc<std::sync::Mutex<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<std::sync::Mutex<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<std::sync::Mutex<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<std::sync::Mutex<#inner_ty>>>,> {
4135                                    rust_key_paths::Kp::new(
4136                                        |root: &#name| root.#idx_lit.as_ref(),
4137                                        |root: &mut #name| root.#idx_lit.as_mut(),
4138                                    )
4139                                }
4140                            });
4141                        }
4142                        (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
4143                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4144                            tokens.extend(quote! {
4145                                #[inline(always)]
4146                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4147    #name,
4148    #ty,
4149    &'a #name,
4150    &'a #ty,
4151    &'a mut #name,
4152    &'a mut #ty,
4153    impl Fn(&'a #name) -> Option<&'a #ty>,
4154    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4155> {
4156                                    rust_key_paths::Kp::new(
4157                                        |root: &#name| Some(&root.#idx_lit),
4158                                        |root: &mut #name| Some(&mut root.#idx_lit),
4159                                    )
4160                                }
4161                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, &'a #name, &'a std::sync::Arc<parking_lot::Mutex<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<parking_lot::Mutex<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<parking_lot::Mutex<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<parking_lot::Mutex<#inner_ty>>>,> {
4162                                    rust_key_paths::Kp::new(
4163                                        |root: &#name| root.#idx_lit.as_ref(),
4164                                        |root: &mut #name| root.#idx_lit.as_mut(),
4165                                    )
4166                                }
4167                            });
4168                        }
4169                        (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
4170                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4171                            tokens.extend(quote! {
4172                                #[inline(always)]
4173                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4174    #name,
4175    #ty,
4176    &'a #name,
4177    &'a #ty,
4178    &'a mut #name,
4179    &'a mut #ty,
4180    impl Fn(&'a #name) -> Option<&'a #ty>,
4181    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4182> {
4183                                    rust_key_paths::Kp::new(
4184                                        |root: &#name| Some(&root.#idx_lit),
4185                                        |root: &mut #name| Some(&mut root.#idx_lit),
4186                                    )
4187                                }
4188                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, &'a #name, &'a std::sync::Arc<std::sync::RwLock<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<std::sync::RwLock<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<std::sync::RwLock<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<std::sync::RwLock<#inner_ty>>>,> {
4189                                    rust_key_paths::Kp::new(
4190                                        |root: &#name| root.#idx_lit.as_ref(),
4191                                        |root: &mut #name| root.#idx_lit.as_mut(),
4192                                    )
4193                                }
4194                            });
4195                        }
4196                        (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
4197                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4198                            tokens.extend(quote! {
4199                                #[inline(always)]
4200                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4201    #name,
4202    #ty,
4203    &'a #name,
4204    &'a #ty,
4205    &'a mut #name,
4206    &'a mut #ty,
4207    impl Fn(&'a #name) -> Option<&'a #ty>,
4208    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4209> {
4210                                    rust_key_paths::Kp::new(
4211                                        |root: &#name| Some(&root.#idx_lit),
4212                                        |root: &mut #name| Some(&mut root.#idx_lit),
4213                                    )
4214                                }
4215                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, &'a #name, &'a std::sync::Arc<parking_lot::RwLock<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<parking_lot::RwLock<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<parking_lot::RwLock<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<parking_lot::RwLock<#inner_ty>>>,> {
4216                                    rust_key_paths::Kp::new(
4217                                        |root: &#name| root.#idx_lit.as_ref(),
4218                                        |root: &mut #name| root.#idx_lit.as_mut(),
4219                                    )
4220                                }
4221                            });
4222                        }
4223                        (WrapperKind::OptionStdMutex, Some(inner_ty)) => {
4224                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4225                            tokens.extend(quote! {
4226                                #[inline(always)]
4227                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4228    #name,
4229    #ty,
4230    &'a #name,
4231    &'a #ty,
4232    &'a mut #name,
4233    &'a mut #ty,
4234    impl Fn(&'a #name) -> Option<&'a #ty>,
4235    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4236> {
4237                                    rust_key_paths::Kp::new(
4238                                        |root: &#name| Some(&root.#idx_lit),
4239                                        |root: &mut #name| Some(&mut root.#idx_lit),
4240                                    )
4241                                }
4242                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
4243    #name,
4244    std::sync::Mutex<#inner_ty>,
4245    &'a #name,
4246    &'a std::sync::Mutex<#inner_ty>,
4247    &'a mut #name,
4248    &'a mut std::sync::Mutex<#inner_ty>,
4249    impl Fn(&'a #name) -> Option<&'a std::sync::Mutex<#inner_ty>>,
4250    impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Mutex<#inner_ty>>,
4251> {
4252                                    rust_key_paths::Kp::new(
4253                                        |root: &#name| root.#idx_lit.as_ref(),
4254                                        |root: &mut #name| root.#idx_lit.as_mut(),
4255                                    )
4256                                }
4257                            });
4258                        }
4259                        (WrapperKind::OptionMutex, Some(inner_ty)) => {
4260                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4261                            tokens.extend(quote! {
4262                                #[inline(always)]
4263                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4264    #name,
4265    #ty,
4266    &'a #name,
4267    &'a #ty,
4268    &'a mut #name,
4269    &'a mut #ty,
4270    impl Fn(&'a #name) -> Option<&'a #ty>,
4271    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4272> {
4273                                    rust_key_paths::Kp::new(
4274                                        |root: &#name| Some(&root.#idx_lit),
4275                                        |root: &mut #name| Some(&mut root.#idx_lit),
4276                                    )
4277                                }
4278                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
4279    #name,
4280    parking_lot::Mutex<#inner_ty>,
4281    &'a #name,
4282    &'a parking_lot::Mutex<#inner_ty>,
4283    &'a mut #name,
4284    &'a mut parking_lot::Mutex<#inner_ty>,
4285    impl Fn(&'a #name) -> Option<&'a parking_lot::Mutex<#inner_ty>>,
4286    impl Fn(&'a mut #name) -> Option<&'a mut parking_lot::Mutex<#inner_ty>>,
4287> {
4288                                    rust_key_paths::Kp::new(
4289                                        |root: &#name| root.#idx_lit.as_ref(),
4290                                        |root: &mut #name| root.#idx_lit.as_mut(),
4291                                    )
4292                                }
4293                            });
4294                        }
4295                        (WrapperKind::OptionStdRwLock, Some(inner_ty)) => {
4296                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4297                            tokens.extend(quote! {
4298                                #[inline(always)]
4299                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4300    #name,
4301    #ty,
4302    &'a #name,
4303    &'a #ty,
4304    &'a mut #name,
4305    &'a mut #ty,
4306    impl Fn(&'a #name) -> Option<&'a #ty>,
4307    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4308> {
4309                                    rust_key_paths::Kp::new(
4310                                        |root: &#name| Some(&root.#idx_lit),
4311                                        |root: &mut #name| Some(&mut root.#idx_lit),
4312                                    )
4313                                }
4314                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
4315    #name,
4316    std::sync::RwLock<#inner_ty>,
4317    &'a #name,
4318    &'a std::sync::RwLock<#inner_ty>,
4319    &'a mut #name,
4320    &'a mut std::sync::RwLock<#inner_ty>,
4321    impl Fn(&'a #name) -> Option<&'a std::sync::RwLock<#inner_ty>>,
4322    impl Fn(&'a mut #name) -> Option<&'a mut std::sync::RwLock<#inner_ty>>,
4323> {
4324                                    rust_key_paths::Kp::new(
4325                                        |root: &#name| root.#idx_lit.as_ref(),
4326                                        |root: &mut #name| root.#idx_lit.as_mut(),
4327                                    )
4328                                }
4329                            });
4330                        }
4331                        (WrapperKind::OptionRwLock, Some(inner_ty)) => {
4332                            let kp_unlocked_fn = format_ident!("f{}_unlocked", idx);
4333                            tokens.extend(quote! {
4334                                #[inline(always)]
4335                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4336    #name,
4337    #ty,
4338    &'a #name,
4339    &'a #ty,
4340    &'a mut #name,
4341    &'a mut #ty,
4342    impl Fn(&'a #name) -> Option<&'a #ty>,
4343    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4344> {
4345                                    rust_key_paths::Kp::new(
4346                                        |root: &#name| Some(&root.#idx_lit),
4347                                        |root: &mut #name| Some(&mut root.#idx_lit),
4348                                    )
4349                                }
4350                                pub fn #kp_unlocked_fn<'a>() -> rust_key_paths::Kp<
4351    #name,
4352    parking_lot::RwLock<#inner_ty>,
4353    &'a #name,
4354    &'a parking_lot::RwLock<#inner_ty>,
4355    &'a mut #name,
4356    &'a mut parking_lot::RwLock<#inner_ty>,
4357    impl Fn(&'a #name) -> Option<&'a parking_lot::RwLock<#inner_ty>>,
4358    impl Fn(&'a mut #name) -> Option<&'a mut parking_lot::RwLock<#inner_ty>>,
4359> {
4360                                    rust_key_paths::Kp::new(
4361                                        |root: &#name| root.#idx_lit.as_ref(),
4362                                        |root: &mut #name| root.#idx_lit.as_mut(),
4363                                    )
4364                                }
4365                            });
4366                        }
4367                        (WrapperKind::Weak, Some(_inner_ty)) => {
4368                            tokens.extend(quote! {
4369                                #[inline(always)]
4370                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4371    #name,
4372    #ty,
4373    &'a #name,
4374    &'a #ty,
4375    &'a mut #name,
4376    &'a mut #ty,
4377    impl Fn(&'a #name) -> Option<&'a #ty>,
4378    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4379> {
4380                                    rust_key_paths::Kp::new(
4381                                        |root: &#name| Some(&root.#idx_lit),
4382                                        |_root: &mut #name| None,
4383                                    )
4384                                }
4385                            });
4386                        }
4387                        (WrapperKind::Atomic, None | Some(_)) => {
4388                            tokens.extend(quote! {
4389                                #[inline(always)]
4390                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4391    #name,
4392    #ty,
4393    &'a #name,
4394    &'a #ty,
4395    &'a mut #name,
4396    &'a mut #ty,
4397    impl Fn(&'a #name) -> Option<&'a #ty>,
4398    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4399> {
4400                                    rust_key_paths::Kp::new(
4401                                        |root: &#name| Some(&root.#idx_lit),
4402                                        |root: &mut #name| Some(&mut root.#idx_lit),
4403                                    )
4404                                }
4405                            });
4406                        }
4407                        (WrapperKind::OptionAtomic, Some(inner_ty)) => {
4408                            tokens.extend(quote! {
4409                                #[inline(always)]
4410                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4411    #name,
4412    #inner_ty,
4413    &'a #name,
4414    &'a #inner_ty,
4415    &'a mut #name,
4416    &'a mut #inner_ty,
4417    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
4418    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
4419> {
4420                                    rust_key_paths::Kp::new(
4421                                        |root: &#name| root.#idx_lit.as_ref(),
4422                                        |root: &mut #name| root.#idx_lit.as_mut(),
4423                                    )
4424                                }
4425                            });
4426                        }
4427                        (WrapperKind::String, None) => {
4428                            tokens.extend(quote! {
4429                                #[inline(always)]
4430                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4431    #name,
4432    #ty,
4433    &'a #name,
4434    &'a #ty,
4435    &'a mut #name,
4436    &'a mut #ty,
4437    impl Fn(&'a #name) -> Option<&'a #ty>,
4438    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4439> {
4440                                    rust_key_paths::Kp::new(
4441                                        |root: &#name| Some(&root.#idx_lit),
4442                                        |root: &mut #name| Some(&mut root.#idx_lit),
4443                                    )
4444                                }
4445                            });
4446                        }
4447                        (WrapperKind::OptionString, None) => {
4448                            tokens.extend(quote! {
4449                                #[inline(always)]
4450                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<#name, std::string::String, &'a #name, &'a std::string::String, &'a mut #name, &'a mut std::string::String, impl Fn(&'a #name) -> Option<&'a std::string::String>, impl Fn(&'a mut #name) -> Option<&'a mut std::string::String>,>  {
4451                                    rust_key_paths::Kp::new(
4452                                        |root: &#name| root.#idx_lit.as_ref(),
4453                                        |root: &mut #name| root.#idx_lit.as_mut(),
4454                                    )
4455                                }
4456                            });
4457                        }
4458                        (WrapperKind::OnceCell, Some(inner_ty)) => {
4459                            tokens.extend(quote! {
4460                                #[inline(always)]
4461                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4462    #name,
4463    #inner_ty,
4464    &'a #name,
4465    &'a #inner_ty,
4466    &'a mut #name,
4467    &'a mut #inner_ty,
4468    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
4469    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
4470> {
4471                                    rust_key_paths::Kp::new(
4472                                        |root: &#name| root.#idx_lit.get(),
4473                                        |_root: &mut #name| None,
4474                                    )
4475                                }
4476                            });
4477                        }
4478                        (WrapperKind::Lazy, Some(inner_ty)) => {
4479                            tokens.extend(quote! {
4480                                #[inline(always)]
4481                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4482    #name,
4483    #inner_ty,
4484    &'a #name,
4485    &'a #inner_ty,
4486    &'a mut #name,
4487    &'a mut #inner_ty,
4488    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
4489    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
4490> {
4491                                    rust_key_paths::Kp::new(
4492                                        |root: &#name| Some(root.#idx_lit.get()),
4493                                        |_root: &mut #name| None,
4494                                    )
4495                                }
4496                            });
4497                        }
4498                        (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
4499                            tokens.extend(quote! {
4500                                #[inline(always)]
4501                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4502    #name,
4503    #inner_ty,
4504    &'a #name,
4505    &'a #inner_ty,
4506    &'a mut #name,
4507    &'a mut #inner_ty,
4508    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
4509    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
4510> {
4511                                    rust_key_paths::Kp::new(
4512                                        |root: &#name| root.#idx_lit.as_ref().and_then(|c| c.get()),
4513                                        |_root: &mut #name| None,
4514                                    )
4515                                }
4516                            });
4517                        }
4518                        (WrapperKind::OptionLazy, Some(inner_ty)) => {
4519                            tokens.extend(quote! {
4520                                #[inline(always)]
4521                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4522    #name,
4523    #inner_ty,
4524    &'a #name,
4525    &'a #inner_ty,
4526    &'a mut #name,
4527    &'a mut #inner_ty,
4528    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
4529    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
4530> {
4531                                    rust_key_paths::Kp::new(
4532                                        |root: &#name| root.#idx_lit.as_ref().map(|c| c.get()),
4533                                        |_root: &mut #name| None,
4534                                    )
4535                                }
4536                            });
4537                        }
4538                        (WrapperKind::Cell, Some(_inner_ty))
4539                        | (WrapperKind::RefCell, Some(_inner_ty))
4540                        | (WrapperKind::PhantomData, Some(_inner_ty))
4541                        | (WrapperKind::Range, Some(_inner_ty))
4542                        | (WrapperKind::OptionCell, Some(_inner_ty))
4543                        | (WrapperKind::OptionPhantomData, Some(_inner_ty))
4544                        | (WrapperKind::OptionRange, Some(_inner_ty)) => {
4545                            tokens.extend(quote! {
4546                                #[inline(always)]
4547                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4548    #name,
4549    #ty,
4550    &'a #name,
4551    &'a #ty,
4552    &'a mut #name,
4553    &'a mut #ty,
4554    impl Fn(&'a #name) -> Option<&'a #ty>,
4555    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4556> {
4557                                    rust_key_paths::Kp::new(
4558                                        |root: &#name| Some(&root.#idx_lit),
4559                                        |root: &mut #name| Some(&mut root.#idx_lit),
4560                                    )
4561                                }
4562                            });
4563                        }
4564                        (WrapperKind::OptionRefCell, Some(inner_ty)) => {
4565                            tokens.extend(quote! {
4566                                #[inline(always)]
4567                                pub fn #kp_fn() -> rust_key_paths::KpOptionRefCellType<'_, #name, #inner_ty> {
4568                                    rust_key_paths::Kp::new(
4569                                        |root: &#name| root.#idx_lit.as_ref().map(|r| r.borrow()),
4570                                        |root: &mut #name| root.#idx_lit.as_ref().map(|r| r.borrow_mut()),
4571                                    )
4572                                }
4573                            });
4574                        }
4575                        (WrapperKind::Reference, Some(_inner_ty)) => {
4576                            tokens.extend(quote! {
4577                                #[inline(always)]
4578                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4579    #name,
4580    #ty,
4581    &'a #name,
4582    &'a #ty,
4583    &'a mut #name,
4584    &'a mut #ty,
4585    impl Fn(&'a #name) -> Option<&'a #ty>,
4586    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4587> {
4588                                    rust_key_paths::Kp::new(
4589                                        |root: &#name| Some(&root.#idx_lit),
4590                                        |_root: &mut #name| None,
4591                                    )
4592                                }
4593                            });
4594                        }
4595                        (WrapperKind::None, None) => {
4596                            tokens.extend(quote! {
4597                                #[inline(always)]
4598                                pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4599    #name,
4600    #ty,
4601    &'a #name,
4602    &'a #ty,
4603    &'a mut #name,
4604    &'a mut #ty,
4605    impl Fn(&'a #name) -> Option<&'a #ty>,
4606    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4607> {
4608                                    rust_key_paths::Kp::new(
4609                                        |root: &#name| Some(&root.#idx_lit),
4610                                        |root: &mut #name| Some(&mut root.#idx_lit),
4611                                    )
4612                                }
4613                            });
4614                        }
4615                        _ => {
4616                            tokens.extend(quote! {
4617                                #[inline(always)]
4618                                    pub fn #kp_fn<'a>() -> rust_key_paths::Kp<
4619    #name,
4620    #ty,
4621    &'a #name,
4622    &'a #ty,
4623    &'a mut #name,
4624    &'a mut #ty,
4625    impl Fn(&'a #name) -> Option<&'a #ty>,
4626    impl Fn(&'a mut #name) -> Option<&'a mut #ty>,
4627> {
4628                                    rust_key_paths::Kp::new(
4629                                        |root: &#name| Some(&root.#idx_lit),
4630                                        |root: &mut #name| Some(&mut root.#idx_lit),
4631                                    )
4632                                }
4633                            });
4634                        }
4635                    }
4636                }
4637
4638                tokens
4639            }
4640            Fields::Unit => {
4641                return syn::Error::new(input_span, "Kp derive does not support unit structs")
4642                    .to_compile_error()
4643                    .into();
4644            }
4645        },
4646        Data::Enum(data_enum) => {
4647            let mut tokens = proc_macro2::TokenStream::new();
4648
4649            // Generate identity methods for the enum
4650            tokens.extend(quote! {
4651                /// Returns a generic identity keypath for this type
4652                #[inline(always)]
4653                pub fn identity_typed<'a, Root, MutRoot>() -> rust_key_paths::Kp<
4654                    #name,
4655                    #name,
4656                    Root,
4657                    Root,
4658                    MutRoot,
4659                    MutRoot,
4660                    fn(Root) -> Option<Root>,
4661                    fn(MutRoot) -> Option<MutRoot>,
4662                >
4663                where
4664                    Root: std::borrow::Borrow<#name>,
4665                    MutRoot: std::borrow::BorrowMut<#name>,
4666                {
4667                    rust_key_paths::Kp::new(
4668                        |r: Root| Some(r),
4669                        |r: MutRoot| Some(r)
4670                    )
4671                }
4672
4673                /// Returns a simple identity keypath for this type
4674                #[inline(always)]
4675                pub fn identity<'a>() -> rust_key_paths::Kp<#name, #name, &'a #name, &'a #name, &'a mut #name, &'a mut #name, impl Fn(&'a #name) -> Option<&'a #name>, impl Fn(&'a mut #name) -> Option<&'a mut #name>,> {
4676                    rust_key_paths::Kp::new(
4677                        |r: &#name| Some(r),
4678                        |r: &mut #name| Some(r)
4679                    )
4680                }
4681            });
4682
4683            for variant in data_enum.variants.iter() {
4684                let v_ident = &variant.ident;
4685                let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
4686
4687                match &variant.fields {
4688                    Fields::Unit => {
4689                        // Unit variant - return keypath that checks if enum matches variant
4690                        tokens.extend(quote! {
4691                            #[inline(always)]
4692                            pub fn #snake<'a>() -> rust_key_paths::Kp<#name, (), &'a #name, &'a (), &'a mut #name, &'a mut (), impl Fn(&'a #name) -> Option<&'a ()>, impl Fn(&'a mut #name) -> Option<&'a mut ()>,>  {
4693                                rust_key_paths::Kp::new(
4694                                    |root: &#name| match root {
4695                                        #name::#v_ident => {
4696                                            static UNIT: () = ();
4697                                            Some(&UNIT)
4698                                        },
4699                                        _ => None,
4700                                    },
4701                                    |_root: &mut #name| None, // Can't mutate unit variant
4702                                )
4703                            }
4704                        });
4705                    }
4706                    Fields::Unnamed(unnamed) => {
4707                        if unnamed.unnamed.len() == 1 {
4708                            // Single-field tuple variant
4709                            let field_ty = &unnamed.unnamed[0].ty;
4710                            let (kind, inner_ty) = extract_wrapper_inner_type(field_ty);
4711
4712                            match (kind, inner_ty.clone()) {
4713                                (WrapperKind::Option, Some(inner_ty)) => {
4714                                    tokens.extend(quote! {
4715                                        #[inline(always)]
4716                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
4717    #name,
4718    #inner_ty,
4719    &'a #name,
4720    &'a #inner_ty,
4721    &'a mut #name,
4722    &'a mut #inner_ty,
4723    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
4724    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
4725> {
4726                                            rust_key_paths::Kp::new(
4727                                                |root: &#name| match root {
4728                                                    #name::#v_ident(inner) => inner.as_ref(),
4729                                                    _ => None,
4730                                                },
4731                                                |root: &mut #name| match root {
4732                                                    #name::#v_ident(inner) => inner.as_mut(),
4733                                                    _ => None,
4734                                                },
4735                                            )
4736                                        }
4737                                    });
4738                                }
4739                                (WrapperKind::OptionHashMap, Some(inner_ty)) => {
4740                                    let snake_at = format_ident!("{}_at", snake);
4741                                    if let Some((key_ty, _)) =
4742                                        extract_map_key_value_through_option(field_ty)
4743                                    {
4744                                        tokens.extend(quote! {
4745                                            #[inline(always)]
4746                                            pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4747                                                rust_key_paths::Kp::new(
4748                                                    |root: &#name| match root {
4749                                                        #name::#v_ident(inner) => Some(inner),
4750                                                        _ => None,
4751                                                    },
4752                                                    |root: &mut #name| match root {
4753                                                        #name::#v_ident(inner) => Some(inner),
4754                                                        _ => None,
4755                                                    },
4756                                                )
4757                                            }
4758                                            #[inline(always)]
4759                                            pub fn #snake_at(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
4760                                            where
4761                                                #key_ty: Clone + std::hash::Hash + Eq + 'static,
4762                                            {
4763                                                let key2 = key.clone();
4764                                                rust_key_paths::Kp::new(
4765                                                    Box::new(move |root: &#name| match root {
4766                                                        #name::#v_ident(inner) => inner.as_ref().and_then(|m| m.get(&key)),
4767                                                        _ => None,
4768                                                    }),
4769                                                    Box::new(move |root: &mut #name| match root {
4770                                                        #name::#v_ident(inner) => inner.as_mut().and_then(|m| m.get_mut(&key2)),
4771                                                        _ => None,
4772                                                    }),
4773                                                )
4774                                            }
4775                                        });
4776                                    } else {
4777                                        tokens.extend(quote! {
4778                                            #[inline(always)]
4779                                            pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4780                                                rust_key_paths::Kp::new(
4781                                                    |root: &#name| match root {
4782                                                        #name::#v_ident(inner) => Some(inner),
4783                                                        _ => None,
4784                                                    },
4785                                                    |root: &mut #name| match root {
4786                                                        #name::#v_ident(inner) => Some(inner),
4787                                                        _ => None,
4788                                                    },
4789                                                )
4790                                            }
4791                                        });
4792                                    }
4793                                }
4794                                (WrapperKind::OptionBTreeMap, Some(inner_ty)) => {
4795                                    let snake_at = format_ident!("{}_at", snake);
4796                                    if let Some((key_ty, _)) =
4797                                        extract_map_key_value_through_option(field_ty)
4798                                    {
4799                                        tokens.extend(quote! {
4800                                            #[inline(always)]
4801                                            pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4802                                                rust_key_paths::Kp::new(
4803                                                    |root: &#name| match root {
4804                                                        #name::#v_ident(inner) => Some(inner),
4805                                                        _ => None,
4806                                                    },
4807                                                    |root: &mut #name| match root {
4808                                                        #name::#v_ident(inner) => Some(inner),
4809                                                        _ => None,
4810                                                    },
4811                                                )
4812                                            }
4813                                            #[inline(always)]
4814                                            pub fn #snake_at(key: #key_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
4815                                            where
4816                                                #key_ty: Clone + Ord + 'static,
4817                                            {
4818                                                let key2 = key.clone();
4819                                                rust_key_paths::Kp::new(
4820                                                    Box::new(move |root: &#name| match root {
4821                                                        #name::#v_ident(inner) => inner.as_ref().and_then(|m| m.get(&key)),
4822                                                        _ => None,
4823                                                    }),
4824                                                    Box::new(move |root: &mut #name| match root {
4825                                                        #name::#v_ident(inner) => inner.as_mut().and_then(|m| m.get_mut(&key2)),
4826                                                        _ => None,
4827                                                    }),
4828                                                )
4829                                            }
4830                                        });
4831                                    } else {
4832                                        tokens.extend(quote! {
4833                                            #[inline(always)]
4834                                            pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4835                                                rust_key_paths::Kp::new(
4836                                                    |root: &#name| match root {
4837                                                        #name::#v_ident(inner) => Some(inner),
4838                                                        _ => None,
4839                                                    },
4840                                                    |root: &mut #name| match root {
4841                                                        #name::#v_ident(inner) => Some(inner),
4842                                                        _ => None,
4843                                                    },
4844                                                )
4845                                            }
4846                                        });
4847                                    }
4848                                }
4849                                (WrapperKind::OptionHashSet, Some(inner_ty)) => {
4850                                    let snake_at = format_ident!("{}_at", snake);
4851                                    tokens.extend(quote! {
4852                                        #[inline(always)]
4853                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4854                                            rust_key_paths::Kp::new(
4855                                                |root: &#name| match root {
4856                                                    #name::#v_ident(inner) => Some(inner),
4857                                                    _ => None,
4858                                                },
4859                                                |root: &mut #name| match root {
4860                                                    #name::#v_ident(inner) => Some(inner),
4861                                                    _ => None,
4862                                                },
4863                                            )
4864                                        }
4865
4866                                        /// _at: check if element exists and get reference.
4867                                        /// HashSet does not allow mutable element access (would break hash invariant).
4868                                        #[inline(always)]
4869                                        pub fn #snake_at(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
4870                                        where
4871                                            #inner_ty: Clone + std::hash::Hash + Eq + 'static,
4872                                        {
4873                                            rust_key_paths::Kp::new(
4874                                                Box::new(move |root: &#name| match root {
4875                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|s| s.get(&key)),
4876                                                    _ => None,
4877                                                }),
4878                                                Box::new(move |_root: &mut #name| None),
4879                                            )
4880                                        }
4881                                    });
4882                                }
4883                                (WrapperKind::OptionBTreeSet, Some(inner_ty)) => {
4884                                    let snake_at = format_ident!("{}_at", snake);
4885                                    tokens.extend(quote! {
4886                                        #[inline(always)]
4887                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4888                                            rust_key_paths::Kp::new(
4889                                                |root: &#name| match root {
4890                                                    #name::#v_ident(inner) => Some(inner),
4891                                                    _ => None,
4892                                                },
4893                                                |root: &mut #name| match root {
4894                                                    #name::#v_ident(inner) => Some(inner),
4895                                                    _ => None,
4896                                                },
4897                                            )
4898                                        }
4899
4900                                        /// _at: check if element exists and get reference.
4901                                        /// BTreeSet does not allow mutable element access (would break ordering invariant).
4902                                        #[inline(always)]
4903                                        pub fn #snake_at(key: #inner_ty) -> rust_key_paths::KpDynamic<#name, #inner_ty>
4904                                        where
4905                                            #inner_ty: Clone + Ord + 'static,
4906                                        {
4907                                            rust_key_paths::Kp::new(
4908                                                Box::new(move |root: &#name| match root {
4909                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|s| s.get(&key)),
4910                                                    _ => None,
4911                                                }),
4912                                                Box::new(move |_root: &mut #name| None),
4913                                            )
4914                                        }
4915                                    });
4916                                }
4917                                (WrapperKind::OptionVec, Some(inner_ty)) => {
4918                                    let snake_at = format_ident!("{}_at", snake);
4919                                    tokens.extend(quote! {
4920                                        #[inline(always)]
4921                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4922                                            rust_key_paths::Kp::new(
4923                                                |root: &#name| match root {
4924                                                    #name::#v_ident(inner) => Some(inner),
4925                                                    _ => None,
4926                                                },
4927                                                |root: &mut #name| match root {
4928                                                    #name::#v_ident(inner) => Some(inner),
4929                                                    _ => None,
4930                                                },
4931                                            )
4932                                        }
4933                                        #[inline(always)]
4934                                        pub fn #snake_at(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
4935                                            rust_key_paths::Kp::new(
4936                                                Box::new(move |root: &#name| match root {
4937                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|v| v.get(index)),
4938                                                    _ => None,
4939                                                }),
4940                                                Box::new(move |root: &mut #name| match root {
4941                                                    #name::#v_ident(inner) => inner.as_mut().and_then(|v| v.get_mut(index)),
4942                                                    _ => None,
4943                                                }),
4944                                            )
4945                                        }
4946                                    });
4947                                }
4948                                (WrapperKind::OptionVecDeque, Some(inner_ty)) => {
4949                                    let snake_at = format_ident!("{}_at", snake);
4950                                    tokens.extend(quote! {
4951                                        #[inline(always)]
4952                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4953                                            rust_key_paths::Kp::new(
4954                                                |root: &#name| match root {
4955                                                    #name::#v_ident(inner) => Some(inner),
4956                                                    _ => None,
4957                                                },
4958                                                |root: &mut #name| match root {
4959                                                    #name::#v_ident(inner) => Some(inner),
4960                                                    _ => None,
4961                                                },
4962                                            )
4963                                        }
4964                                        #[inline(always)]
4965                                        pub fn #snake_at(index: usize) -> rust_key_paths::KpDynamic<#name, #inner_ty> {
4966                                            rust_key_paths::Kp::new(
4967                                                Box::new(move |root: &#name| match root {
4968                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|v| v.get(index)),
4969                                                    _ => None,
4970                                                }),
4971                                                Box::new(move |root: &mut #name| match root {
4972                                                    #name::#v_ident(inner) => inner.as_mut().and_then(|v| v.get_mut(index)),
4973                                                    _ => None,
4974                                                }),
4975                                            )
4976                                        }
4977                                    });
4978                                }
4979                                (WrapperKind::OptionLinkedList, Some(_inner_ty))
4980                                | (WrapperKind::OptionBinaryHeap, Some(_inner_ty))
4981                                | (WrapperKind::OptionResult, Some(_inner_ty)) => {
4982                                    tokens.extend(quote! {
4983                                        #[inline(always)]
4984                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
4985                                            rust_key_paths::Kp::new(
4986                                                |root: &#name| match root {
4987                                                    #name::#v_ident(inner) => Some(inner),
4988                                                    _ => None,
4989                                                },
4990                                                |root: &mut #name| match root {
4991                                                    #name::#v_ident(inner) => Some(inner),
4992                                                    _ => None,
4993                                                },
4994                                            )
4995                                        }
4996                                    });
4997                                }
4998                                (WrapperKind::Vec, Some(inner_ty)) => {
4999                                    tokens.extend(quote! {
5000                                        #[inline(always)]
5001                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5002    #name,
5003    #inner_ty,
5004    &'a #name,
5005    &'a #inner_ty,
5006    &'a mut #name,
5007    &'a mut #inner_ty,
5008    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5009    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5010> {
5011                                            rust_key_paths::Kp::new(
5012                                                |root: &#name| match root {
5013                                                    #name::#v_ident(inner) => inner.first(),
5014                                                    _ => None,
5015                                                },
5016                                                |root: &mut #name| match root {
5017                                                    #name::#v_ident(inner) => inner.first_mut(),
5018                                                    _ => None,
5019                                                },
5020                                            )
5021                                        }
5022                                    });
5023                                }
5024                                (WrapperKind::Box, Some(inner_ty)) => {
5025                                    // Box in enum: deref to inner (&T / &mut T)
5026                                    tokens.extend(quote! {
5027                                        #[inline(always)]
5028                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5029    #name,
5030    #inner_ty,
5031    &'a #name,
5032    &'a #inner_ty,
5033    &'a mut #name,
5034    &'a mut #inner_ty,
5035    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5036    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5037> {
5038                                            rust_key_paths::Kp::new(
5039                                                |root: &#name| match root {
5040                                                    #name::#v_ident(inner) => Some(&**inner),
5041                                                    _ => None,
5042                                                },
5043                                                |root: &mut #name| match root {
5044                                                    #name::#v_ident(inner) => Some(&mut **inner),
5045                                                    _ => None,
5046                                                },
5047                                            )
5048                                        }
5049                                    });
5050                                }
5051                                (WrapperKind::Pin, Some(inner_ty)) => {
5052                                    let snake_inner = format_ident!("{}_inner", snake);
5053                                    tokens.extend(quote! {
5054                                        #[inline(always)]
5055                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5056                                            rust_key_paths::Kp::new(
5057                                                |root: &#name| match root {
5058                                                    #name::#v_ident(inner) => Some(inner),
5059                                                    _ => None,
5060                                                },
5061                                                |root: &mut #name| match root {
5062                                                    #name::#v_ident(inner) => Some(inner),
5063                                                    _ => None,
5064                                                },
5065                                            )
5066                                        }
5067                                        #[inline(always)]
5068                                        pub fn #snake_inner<'a>() -> rust_key_paths::Kp<
5069    #name,
5070    #inner_ty,
5071    &'a #name,
5072    &'a #inner_ty,
5073    &'a mut #name,
5074    &'a mut #inner_ty,
5075    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5076    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5077>
5078                                        where #inner_ty: std::marker::Unpin
5079                                        {
5080                                            rust_key_paths::Kp::new(
5081                                                |root: &#name| match root {
5082                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_ref(inner).get_ref()),
5083                                                    _ => None,
5084                                                },
5085                                                |root: &mut #name| match root {
5086                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_mut(inner).get_mut()),
5087                                                    _ => None,
5088                                                },
5089                                            )
5090                                        }
5091                                    });
5092                                }
5093                                (WrapperKind::PinBox, Some(inner_ty)) => {
5094                                    let snake_inner = format_ident!("{}_inner", snake);
5095                                    tokens.extend(quote! {
5096                                        #[inline(always)]
5097                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5098                                            rust_key_paths::Kp::new(
5099                                                |root: &#name| match root {
5100                                                    #name::#v_ident(inner) => Some(inner),
5101                                                    _ => None,
5102                                                },
5103                                                |root: &mut #name| match root {
5104                                                    #name::#v_ident(inner) => Some(inner),
5105                                                    _ => None,
5106                                                },
5107                                            )
5108                                        }
5109                                        #[inline(always)]
5110                                        pub fn #snake_inner<'a>() -> rust_key_paths::Kp<
5111    #name,
5112    #inner_ty,
5113    &'a #name,
5114    &'a #inner_ty,
5115    &'a mut #name,
5116    &'a mut #inner_ty,
5117    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5118    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5119>
5120                                        where #inner_ty: std::marker::Unpin
5121                                        {
5122                                            rust_key_paths::Kp::new(
5123                                                |root: &#name| match root {
5124                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_ref(inner).get_ref()),
5125                                                    _ => None,
5126                                                },
5127                                                |root: &mut #name| match root {
5128                                                    #name::#v_ident(inner) => Some(std::pin::Pin::as_mut(inner).get_mut()),
5129                                                    _ => None,
5130                                                },
5131                                            )
5132                                        }
5133                                    });
5134                                }
5135                                (WrapperKind::Rc, Some(inner_ty)) => {
5136                                    tokens.extend(quote! {
5137                                        #[inline(always)]
5138                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5139    #name,
5140    #inner_ty,
5141    &'a #name,
5142    &'a #inner_ty,
5143    &'a mut #name,
5144    &'a mut #inner_ty,
5145    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5146    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5147> {
5148                                            rust_key_paths::Kp::new(
5149                                                |root: &#name| match root {
5150                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
5151                                                    _ => None,
5152                                                },
5153                                                |root: &mut #name| match root {
5154                                                    #name::#v_ident(inner) => std::rc::Rc::get_mut(inner),
5155                                                    _ => None,
5156                                                },
5157                                            )
5158                                        }
5159                                    });
5160                                }
5161                                (WrapperKind::Arc, Some(inner_ty)) => {
5162                                    tokens.extend(quote! {
5163                                        #[inline(always)]
5164                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5165    #name,
5166    #inner_ty,
5167    &'a #name,
5168    &'a #inner_ty,
5169    &'a mut #name,
5170    &'a mut #inner_ty,
5171    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5172    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5173> {
5174                                            rust_key_paths::Kp::new(
5175                                                |root: &#name| match root {
5176                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
5177                                                    _ => None,
5178                                                },
5179                                                |root: &mut #name| match root {
5180                                                    #name::#v_ident(inner) => std::sync::Arc::get_mut(inner),
5181                                                    _ => None,
5182                                                },
5183                                            )
5184                                        }
5185                                    });
5186                                }
5187                                (WrapperKind::StdArcRwLock, Some(inner_ty)) => {
5188                                    let snake_lock = format_ident!("{}_lock", snake);
5189                                    tokens.extend(quote! {
5190                                        #[inline(always)]
5191                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5192                                            rust_key_paths::Kp::new(
5193                                                |root: &#name| match root {
5194                                                    #name::#v_ident(inner) => Some(inner),
5195                                                    _ => None,
5196                                                },
5197                                                |root: &mut #name| match root {
5198                                                    #name::#v_ident(inner) => Some(inner),
5199                                                    _ => None,
5200                                                },
5201                                            )
5202                                        }
5203                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, #field_ty, #inner_ty> {
5204                                            rust_key_paths::lock::LockKp::new(
5205                                                rust_key_paths::Kp::new(
5206                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5207                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5208                                                ),
5209                                                rust_key_paths::lock::ArcRwLockAccess::new(),
5210                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5211                                            )
5212                                        }
5213                                    });
5214                                }
5215                                (WrapperKind::StdArcMutex, Some(inner_ty)) => {
5216                                    let snake_lock = format_ident!("{}_lock", snake);
5217                                    tokens.extend(quote! {
5218                                        #[inline(always)]
5219                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5220                                            rust_key_paths::Kp::new(
5221                                                |root: &#name| match root {
5222                                                    #name::#v_ident(inner) => Some(inner),
5223                                                    _ => None,
5224                                                },
5225                                                |root: &mut #name| match root {
5226                                                    #name::#v_ident(inner) => Some(inner),
5227                                                    _ => None,
5228                                                },
5229                                            )
5230                                        }
5231                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexFor<#name, #field_ty, #inner_ty> {
5232                                            rust_key_paths::lock::LockKp::new(
5233                                                rust_key_paths::Kp::new(
5234                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5235                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5236                                                ),
5237                                                rust_key_paths::lock::ArcMutexAccess::new(),
5238                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5239                                            )
5240                                        }
5241                                    });
5242                                }
5243                                (WrapperKind::ArcRwLock, Some(inner_ty)) => {
5244                                    let snake_lock = format_ident!("{}_lock", snake);
5245                                    tokens.extend(quote! {
5246                                        #[inline(always)]
5247                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5248                                            rust_key_paths::Kp::new(
5249                                                |root: &#name| match root {
5250                                                    #name::#v_ident(inner) => Some(inner),
5251                                                    _ => None,
5252                                                },
5253                                                |root: &mut #name| match root {
5254                                                    #name::#v_ident(inner) => Some(inner),
5255                                                    _ => None,
5256                                                },
5257                                            )
5258                                        }
5259                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, #field_ty, #inner_ty> {
5260                                            rust_key_paths::lock::LockKp::new(
5261                                                rust_key_paths::Kp::new(
5262                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5263                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5264                                                ),
5265                                                rust_key_paths::lock::ParkingLotRwLockAccess::new(),
5266                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5267                                            )
5268                                        }
5269                                    });
5270                                }
5271                                (WrapperKind::ArcMutex, Some(inner_ty)) => {
5272                                    let snake_lock = format_ident!("{}_lock", snake);
5273                                    tokens.extend(quote! {
5274                                        #[inline(always)]
5275                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5276                                            rust_key_paths::Kp::new(
5277                                                |root: &#name| match root {
5278                                                    #name::#v_ident(inner) => Some(inner),
5279                                                    _ => None,
5280                                                },
5281                                                |root: &mut #name| match root {
5282                                                    #name::#v_ident(inner) => Some(inner),
5283                                                    _ => None,
5284                                                },
5285                                            )
5286                                        }
5287                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, #field_ty, #inner_ty> {
5288                                            rust_key_paths::lock::LockKp::new(
5289                                                rust_key_paths::Kp::new(
5290                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5291                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5292                                                ),
5293                                                rust_key_paths::lock::ParkingLotMutexAccess::new(),
5294                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5295                                            )
5296                                        }
5297                                    });
5298                                }
5299                                (WrapperKind::StdArcMutexOption, Some(inner_ty)) => {
5300                                    let snake_lock = format_ident!("{}_lock", snake);
5301                                    tokens.extend(quote! {
5302                                        #[inline(always)]
5303                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5304                                            rust_key_paths::Kp::new(
5305                                                |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5306                                                |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5307                                            )
5308                                        }
5309                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexOptionFor<#name, #field_ty, #inner_ty> {
5310                                            rust_key_paths::lock::LockKp::new(
5311                                                rust_key_paths::Kp::new(
5312                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5313                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5314                                                ),
5315                                                rust_key_paths::lock::ArcMutexAccess::<Option<#inner_ty>>::new(),
5316                                                rust_key_paths::Kp::new(Option::<#inner_ty>::as_ref, Option::<#inner_ty>::as_mut),
5317                                            )
5318                                        }
5319                                    });
5320                                }
5321                                (WrapperKind::StdArcRwLockOption, Some(inner_ty)) => {
5322                                    let snake_lock = format_ident!("{}_lock", snake);
5323                                    tokens.extend(quote! {
5324                                        #[inline(always)]
5325                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5326                                            rust_key_paths::Kp::new(
5327                                                |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5328                                                |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5329                                            )
5330                                        }
5331                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockOptionFor<#name, #field_ty, #inner_ty> {
5332                                            rust_key_paths::lock::LockKp::new(
5333                                                rust_key_paths::Kp::new(
5334                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5335                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5336                                                ),
5337                                                rust_key_paths::lock::ArcRwLockAccess::<Option<#inner_ty>>::new(),
5338                                                rust_key_paths::Kp::new(Option::<#inner_ty>::as_ref, Option::<#inner_ty>::as_mut),
5339                                            )
5340                                        }
5341                                    });
5342                                }
5343                                (WrapperKind::ArcMutexOption, Some(inner_ty)) => {
5344                                    let snake_lock = format_ident!("{}_lock", snake);
5345                                    tokens.extend(quote! {
5346                                        #[inline(always)]
5347                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5348                                            rust_key_paths::Kp::new(
5349                                                |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5350                                                |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5351                                            )
5352                                        }
5353                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexOptionFor<#name, #field_ty, #inner_ty> {
5354                                            rust_key_paths::lock::LockKp::new(
5355                                                rust_key_paths::Kp::new(
5356                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5357                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5358                                                ),
5359                                                rust_key_paths::lock::ParkingLotMutexAccess::<Option<#inner_ty>>::new(),
5360                                                rust_key_paths::Kp::new(Option::<#inner_ty>::as_ref, Option::<#inner_ty>::as_mut),
5361                                            )
5362                                        }
5363                                    });
5364                                }
5365                                (WrapperKind::ArcRwLockOption, Some(inner_ty)) => {
5366                                    let snake_lock = format_ident!("{}_lock", snake);
5367                                    tokens.extend(quote! {
5368                                        #[inline(always)]
5369                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5370                                            rust_key_paths::Kp::new(
5371                                                |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5372                                                |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5373                                            )
5374                                        }
5375                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockOptionFor<#name, #field_ty, #inner_ty> {
5376                                            rust_key_paths::lock::LockKp::new(
5377                                                rust_key_paths::Kp::new(
5378                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5379                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5380                                                ),
5381                                                rust_key_paths::lock::ParkingLotRwLockAccess::<Option<#inner_ty>>::new(),
5382                                                rust_key_paths::Kp::new(Option::<#inner_ty>::as_ref, Option::<#inner_ty>::as_mut),
5383                                            )
5384                                        }
5385                                    });
5386                                }
5387                                (WrapperKind::TokioArcMutex, Some(inner_ty)) => {
5388                                    let snake_async = format_ident!("{}_kp", snake);
5389                                    tokens.extend(quote! {
5390                                        #[inline(always)]
5391                                        pub fn #snake_async<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5392                                            rust_key_paths::Kp::new(
5393                                                |root: &#name| match root {
5394                                                    #name::#v_ident(inner) => Some(inner),
5395                                                    _ => None,
5396                                                },
5397                                                |root: &mut #name| match root {
5398                                                    #name::#v_ident(inner) => Some(inner),
5399                                                    _ => None,
5400                                                },
5401                                            )
5402                                        }
5403                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, #field_ty, #inner_ty> {
5404                                            rust_key_paths::async_lock::AsyncLockKp::new(
5405                                                rust_key_paths::Kp::new(
5406                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5407                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5408                                                ),
5409                                                rust_key_paths::async_lock::TokioMutexAccess::new(),
5410                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5411                                            )
5412                                        }
5413                                    });
5414                                }
5415                                (WrapperKind::TokioArcRwLock, Some(inner_ty)) => {
5416                                    let snake_async = format_ident!("{}_kp", snake);
5417                                    tokens.extend(quote! {
5418                                        #[inline(always)]
5419                                        pub fn #snake_async<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5420                                            rust_key_paths::Kp::new(
5421                                                |root: &#name| match root {
5422                                                    #name::#v_ident(inner) => Some(inner),
5423                                                    _ => None,
5424                                                },
5425                                                |root: &mut #name| match root {
5426                                                    #name::#v_ident(inner) => Some(inner),
5427                                                    _ => None,
5428                                                },
5429                                            )
5430                                        }
5431                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, #field_ty, #inner_ty> {
5432                                            rust_key_paths::async_lock::AsyncLockKp::new(
5433                                                rust_key_paths::Kp::new(
5434                                                    |root: &#name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5435                                                    |root: &mut #name| match root { #name::#v_ident(inner) => Some(inner), _ => None },
5436                                                ),
5437                                                rust_key_paths::async_lock::TokioRwLockAccess::new(),
5438                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5439                                            )
5440                                        }
5441                                    });
5442                                }
5443                                (WrapperKind::OptionTokioArcMutex, Some(inner_ty)) => {
5444                                    let snake_async = format_ident!("{}_kp", snake);
5445                                    tokens.extend(quote! {
5446                                        #[inline(always)]
5447                                        pub fn #snake_async<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5448                                            rust_key_paths::Kp::new(
5449                                                |root: &#name| match root {
5450                                                    #name::#v_ident(inner) => Some(inner),
5451                                                    _ => None,
5452                                                },
5453                                                |root: &mut #name| match root {
5454                                                    #name::#v_ident(inner) => Some(inner),
5455                                                    _ => None,
5456                                                },
5457                                            )
5458                                        }
5459                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpMutexFor<#name, std::sync::Arc<tokio::sync::Mutex<#inner_ty>>, #inner_ty> {
5460                                            rust_key_paths::async_lock::AsyncLockKp::new(
5461                                                rust_key_paths::Kp::new(
5462                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5463                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5464                                                ),
5465                                                rust_key_paths::async_lock::TokioMutexAccess::new(),
5466                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5467                                            )
5468                                        }
5469                                    });
5470                                }
5471                                (WrapperKind::OptionTokioArcRwLock, Some(inner_ty)) => {
5472                                    let snake_async = format_ident!("{}_kp", snake);
5473                                    tokens.extend(quote! {
5474                                        #[inline(always)]
5475                                        pub fn #snake_async<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5476                                            rust_key_paths::Kp::new(
5477                                                |root: &#name| match root {
5478                                                    #name::#v_ident(inner) => Some(inner),
5479                                                    _ => None,
5480                                                },
5481                                                |root: &mut #name| match root {
5482                                                    #name::#v_ident(inner) => Some(inner),
5483                                                    _ => None,
5484                                                },
5485                                            )
5486                                        }
5487                                        pub fn #snake() -> rust_key_paths::async_lock::AsyncLockKpRwLockFor<#name, std::sync::Arc<tokio::sync::RwLock<#inner_ty>>, #inner_ty> {
5488                                            rust_key_paths::async_lock::AsyncLockKp::new(
5489                                                rust_key_paths::Kp::new(
5490                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5491                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5492                                                ),
5493                                                rust_key_paths::async_lock::TokioRwLockAccess::new(),
5494                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5495                                            )
5496                                        }
5497                                    });
5498                                }
5499                                (WrapperKind::OptionStdArcMutex, Some(inner_ty)) => {
5500                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
5501                                    let snake_lock = format_ident!("{}_lock", snake);
5502                                    tokens.extend(quote! {
5503                                        #[inline(always)]
5504                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5505                                            rust_key_paths::Kp::new(
5506                                                |root: &#name| match root {
5507                                                    #name::#v_ident(inner) => Some(inner),
5508                                                    _ => None,
5509                                                },
5510                                                |root: &mut #name| match root {
5511                                                    #name::#v_ident(inner) => Some(inner),
5512                                                    _ => None,
5513                                                },
5514                                            )
5515                                        }
5516                                        pub fn #snake_unlocked<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, &'a #name, &'a std::sync::Arc<std::sync::Mutex<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<std::sync::Mutex<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<std::sync::Mutex<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<std::sync::Mutex<#inner_ty>>>,> {
5517                                            rust_key_paths::Kp::new(
5518                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5519                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5520                                            )
5521                                        }
5522                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcMutexFor<#name, std::sync::Arc<std::sync::Mutex<#inner_ty>>, #inner_ty> {
5523                                            rust_key_paths::lock::LockKp::new(
5524                                                rust_key_paths::Kp::new(
5525                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5526                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5527                                                ),
5528                                                rust_key_paths::lock::ArcMutexAccess::new(),
5529                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5530                                            )
5531                                        }
5532                                    });
5533                                }
5534                                (WrapperKind::OptionArcMutex, Some(inner_ty)) => {
5535                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
5536                                    let snake_lock = format_ident!("{}_lock", snake);
5537                                    tokens.extend(quote! {
5538                                        #[inline(always)]
5539                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5540                                            rust_key_paths::Kp::new(
5541                                                |root: &#name| match root {
5542                                                    #name::#v_ident(inner) => Some(inner),
5543                                                    _ => None,
5544                                                },
5545                                                |root: &mut #name| match root {
5546                                                    #name::#v_ident(inner) => Some(inner),
5547                                                    _ => None,
5548                                                },
5549                                            )
5550                                        }
5551                                        pub fn #snake_unlocked<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, &'a #name, &'a std::sync::Arc<parking_lot::Mutex<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<parking_lot::Mutex<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<parking_lot::Mutex<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<parking_lot::Mutex<#inner_ty>>>,> {
5552                                            rust_key_paths::Kp::new(
5553                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5554                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5555                                            )
5556                                        }
5557                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotMutexFor<#name, std::sync::Arc<parking_lot::Mutex<#inner_ty>>, #inner_ty> {
5558                                            rust_key_paths::lock::LockKp::new(
5559                                                rust_key_paths::Kp::new(
5560                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5561                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5562                                                ),
5563                                                rust_key_paths::lock::ParkingLotMutexAccess::new(),
5564                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5565                                            )
5566                                        }
5567                                    });
5568                                }
5569                                (WrapperKind::OptionStdArcRwLock, Some(inner_ty)) => {
5570                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
5571                                    let snake_lock = format_ident!("{}_lock", snake);
5572                                    tokens.extend(quote! {
5573                                        #[inline(always)]
5574                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5575                                            rust_key_paths::Kp::new(
5576                                                |root: &#name| match root {
5577                                                    #name::#v_ident(inner) => Some(inner),
5578                                                    _ => None,
5579                                                },
5580                                                |root: &mut #name| match root {
5581                                                    #name::#v_ident(inner) => Some(inner),
5582                                                    _ => None,
5583                                                },
5584                                            )
5585                                        }
5586                                        pub fn #snake_unlocked<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, &'a #name, &'a std::sync::Arc<std::sync::RwLock<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<std::sync::RwLock<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<std::sync::RwLock<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<std::sync::RwLock<#inner_ty>>>,> {
5587                                            rust_key_paths::Kp::new(
5588                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5589                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5590                                            )
5591                                        }
5592                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpArcRwLockFor<#name, std::sync::Arc<std::sync::RwLock<#inner_ty>>, #inner_ty> {
5593                                            rust_key_paths::lock::LockKp::new(
5594                                                rust_key_paths::Kp::new(
5595                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5596                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5597                                                ),
5598                                                rust_key_paths::lock::ArcRwLockAccess::new(),
5599                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5600                                            )
5601                                        }
5602                                    });
5603                                }
5604                                (WrapperKind::OptionArcRwLock, Some(inner_ty)) => {
5605                                    let snake_unlocked = format_ident!("{}_unlocked", snake);
5606                                    let snake_lock = format_ident!("{}_lock", snake);
5607                                    tokens.extend(quote! {
5608                                        #[inline(always)]
5609                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5610                                            rust_key_paths::Kp::new(
5611                                                |root: &#name| match root {
5612                                                    #name::#v_ident(inner) => Some(inner),
5613                                                    _ => None,
5614                                                },
5615                                                |root: &mut #name| match root {
5616                                                    #name::#v_ident(inner) => Some(inner),
5617                                                    _ => None,
5618                                                },
5619                                            )
5620                                        }
5621                                        pub fn #snake_unlocked<'a>() -> rust_key_paths::Kp<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, &'a #name, &'a std::sync::Arc<parking_lot::RwLock<#inner_ty>>, &'a mut #name, &'a mut std::sync::Arc<parking_lot::RwLock<#inner_ty>>, impl Fn(&'a #name) -> Option<&'a std::sync::Arc<parking_lot::RwLock<#inner_ty>>>, impl Fn(&'a mut #name) -> Option<&'a mut std::sync::Arc<parking_lot::RwLock<#inner_ty>>>,> {
5622                                            rust_key_paths::Kp::new(
5623                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5624                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5625                                            )
5626                                        }
5627                                        pub fn #snake_lock() -> rust_key_paths::lock::LockKpParkingLotRwLockFor<#name, std::sync::Arc<parking_lot::RwLock<#inner_ty>>, #inner_ty> {
5628                                            rust_key_paths::lock::LockKp::new(
5629                                                rust_key_paths::Kp::new(
5630                                                    |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5631                                                    |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5632                                                ),
5633                                                rust_key_paths::lock::ParkingLotRwLockAccess::new(),
5634                                                rust_key_paths::Kp::new(|v: &#inner_ty| Some(v), |v: &mut #inner_ty| Some(v)),
5635                                            )
5636                                        }
5637                                    });
5638                                }
5639                                (WrapperKind::StdMutex, Some(_inner_ty))
5640                                | (WrapperKind::Mutex, Some(_inner_ty))
5641                                | (WrapperKind::StdRwLock, Some(_inner_ty))
5642                                | (WrapperKind::RwLock, Some(_inner_ty)) => {
5643                                    tokens.extend(quote! {
5644                                        #[inline(always)]
5645                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5646                                            rust_key_paths::Kp::new(
5647                                                |root: &#name| match root {
5648                                                    #name::#v_ident(inner) => Some(inner),
5649                                                    _ => None,
5650                                                },
5651                                                |root: &mut #name| match root {
5652                                                    #name::#v_ident(inner) => Some(inner),
5653                                                    _ => None,
5654                                                },
5655                                            )
5656                                        }
5657                                    });
5658                                }
5659                                (WrapperKind::Tagged, Some(inner_ty)) => {
5660                                    tokens.extend(quote! {
5661                                        #[inline(always)]
5662                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5663    #name,
5664    #inner_ty,
5665    &'a #name,
5666    &'a #inner_ty,
5667    &'a mut #name,
5668    &'a mut #inner_ty,
5669    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5670    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5671> {
5672                                            rust_key_paths::Kp::new(
5673                                                |root: &#name| match root {
5674                                                    #name::#v_ident(inner) => Some(std::ops::Deref::deref(inner)),
5675                                                    _ => None,
5676                                                },
5677                                                |root: &mut #name| match root {
5678                                                    #name::#v_ident(inner) => Some(std::ops::DerefMut::deref_mut(inner)),
5679                                                    _ => None,
5680                                                },
5681                                            )
5682                                        }
5683                                    });
5684                                }
5685                                (WrapperKind::Atomic, None | Some(_)) => {
5686                                    tokens.extend(quote! {
5687                                        #[inline(always)]
5688                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5689                                            rust_key_paths::Kp::new(
5690                                                |root: &#name| match root {
5691                                                    #name::#v_ident(inner) => Some(inner),
5692                                                    _ => None,
5693                                                },
5694                                                |root: &mut #name| match root {
5695                                                    #name::#v_ident(inner) => Some(inner),
5696                                                    _ => None,
5697                                                },
5698                                            )
5699                                        }
5700                                    });
5701                                }
5702                                (WrapperKind::OptionAtomic, Some(inner_ty)) => {
5703                                    tokens.extend(quote! {
5704                                        #[inline(always)]
5705                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5706    #name,
5707    #inner_ty,
5708    &'a #name,
5709    &'a #inner_ty,
5710    &'a mut #name,
5711    &'a mut #inner_ty,
5712    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5713    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5714> {
5715                                            rust_key_paths::Kp::new(
5716                                                |root: &#name| match root { #name::#v_ident(inner) => inner.as_ref(), _ => None },
5717                                                |root: &mut #name| match root { #name::#v_ident(inner) => inner.as_mut(), _ => None },
5718                                            )
5719                                        }
5720                                    });
5721                                }
5722                                (WrapperKind::Reference, Some(_inner_ty)) => {
5723                                    tokens.extend(quote! {
5724                                        #[inline(always)]
5725                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5726                                            rust_key_paths::Kp::new(
5727                                                |root: &#name| match root {
5728                                                    #name::#v_ident(inner) => Some(inner),
5729                                                    _ => None,
5730                                                },
5731                                                |_root: &mut #name| None,
5732                                            )
5733                                        }
5734                                    });
5735                                }
5736                                (WrapperKind::Weak, Some(_inner_ty)) => {
5737                                    tokens.extend(quote! {
5738                                        #[inline(always)]
5739                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
5740                                            rust_key_paths::Kp::new(
5741                                                |root: &#name| match root {
5742                                                    #name::#v_ident(inner) => Some(inner),
5743                                                    _ => None,
5744                                                },
5745                                                |_root: &mut #name| None,
5746                                            )
5747                                        }
5748                                    });
5749                                }
5750                                (WrapperKind::Cow, Some(inner_ty)) => {
5751                                    tokens.extend(quote! {
5752                                        #[inline(always)]
5753                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5754    #name,
5755    #inner_ty,
5756    &'a #name,
5757    &'a #inner_ty,
5758    &'a mut #name,
5759    &'a mut #inner_ty,
5760    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5761    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5762> {
5763                                            rust_key_paths::Kp::new(
5764                                                |root: &#name| match root {
5765                                                    #name::#v_ident(inner) => Some(inner.as_ref()),
5766                                                    _ => None,
5767                                                },
5768                                                |root: &mut #name| match root {
5769                                                    #name::#v_ident(inner) => Some(inner.to_mut()),
5770                                                    _ => None,
5771                                                },
5772                                            )
5773                                        }
5774                                    });
5775                                }
5776                                (WrapperKind::OptionBox, Some(inner_ty)) => {
5777                                    // Option<Box<T>>: keypath to T via as_deref() / as_deref_mut()
5778                                    tokens.extend(quote! {
5779                                        #[inline(always)]
5780                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5781    #name,
5782    #inner_ty,
5783    &'a #name,
5784    &'a #inner_ty,
5785    &'a mut #name,
5786    &'a mut #inner_ty,
5787    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5788    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5789> {
5790                                            rust_key_paths::Kp::new(
5791                                                |root: &#name| match root {
5792                                                    #name::#v_ident(inner) => inner.as_deref(),
5793                                                    _ => None,
5794                                                },
5795                                                |root: &mut #name| match root {
5796                                                    #name::#v_ident(inner) => inner.as_deref_mut(),
5797                                                    _ => None,
5798                                                },
5799                                            )
5800                                        }
5801                                    });
5802                                }
5803                                (WrapperKind::BoxOption, Some(inner_ty)) => {
5804                                    // Box<Option<T>>: keypath to T; inner is &Box<Option<T>>, deref then Option::as_ref/as_mut
5805                                    tokens.extend(quote! {
5806                                        #[inline(always)]
5807                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5808    #name,
5809    #inner_ty,
5810    &'a #name,
5811    &'a #inner_ty,
5812    &'a mut #name,
5813    &'a mut #inner_ty,
5814    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5815    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5816> {
5817                                            rust_key_paths::Kp::new(
5818                                                |root: &#name| match root {
5819                                                    #name::#v_ident(inner) => (&*inner).as_ref(),
5820                                                    _ => None,
5821                                                },
5822                                                |root: &mut #name| match root {
5823                                                    #name::#v_ident(inner) => (&mut *inner).as_mut(),
5824                                                    _ => None,
5825                                                },
5826                                            )
5827                                        }
5828                                    });
5829                                }
5830                                (WrapperKind::RcOption, Some(inner_ty)) => {
5831                                    // Rc<Option<T>>: keypath to T; get = (&*inner).as_ref(), set = Rc::get_mut then as_mut
5832                                    tokens.extend(quote! {
5833                                        #[inline(always)]
5834                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5835    #name,
5836    #inner_ty,
5837    &'a #name,
5838    &'a #inner_ty,
5839    &'a mut #name,
5840    &'a mut #inner_ty,
5841    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5842    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5843> {
5844                                            rust_key_paths::Kp::new(
5845                                                |root: &#name| match root {
5846                                                    #name::#v_ident(inner) => (&*inner).as_ref(),
5847                                                    _ => None,
5848                                                },
5849                                                |root: &mut #name| match root {
5850                                                    #name::#v_ident(inner) => std::rc::Rc::get_mut(inner).and_then(std::option::Option::as_mut),
5851                                                    _ => None,
5852                                                },
5853                                            )
5854                                        }
5855                                    });
5856                                }
5857                                (WrapperKind::ArcOption, Some(inner_ty)) => {
5858                                    // Arc<Option<T>>: keypath to T; get = (&*inner).as_ref(), set = Arc::get_mut then as_mut
5859                                    tokens.extend(quote! {
5860                                        #[inline(always)]
5861                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5862    #name,
5863    #inner_ty,
5864    &'a #name,
5865    &'a #inner_ty,
5866    &'a mut #name,
5867    &'a mut #inner_ty,
5868    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5869    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5870> {
5871                                            rust_key_paths::Kp::new(
5872                                                |root: &#name| match root {
5873                                                    #name::#v_ident(inner) => (&*inner).as_ref(),
5874                                                    _ => None,
5875                                                },
5876                                                |root: &mut #name| match root {
5877                                                    #name::#v_ident(inner) => std::sync::Arc::get_mut(inner).and_then(std::option::Option::as_mut),
5878                                                    _ => None,
5879                                                },
5880                                            )
5881                                        }
5882                                    });
5883                                }
5884                                (WrapperKind::OptionRc, Some(inner_ty)) => {
5885                                    tokens.extend(quote! {
5886                                        #[inline(always)]
5887                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5888    #name,
5889    #inner_ty,
5890    &'a #name,
5891    &'a #inner_ty,
5892    &'a mut #name,
5893    &'a mut #inner_ty,
5894    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5895    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5896> {
5897                                            rust_key_paths::Kp::new(
5898                                                |root: &#name| match root {
5899                                                    #name::#v_ident(inner) => inner.as_deref(),
5900                                                    _ => None,
5901                                                },
5902                                                |root: &mut #name| match root {
5903                                                    #name::#v_ident(inner) => inner.as_mut().and_then(std::rc::Rc::get_mut),
5904                                                    _ => None,
5905                                                },
5906                                            )
5907                                        }
5908                                    });
5909                                }
5910                                (WrapperKind::OptionArc, Some(inner_ty)) => {
5911                                    tokens.extend(quote! {
5912                                        #[inline(always)]
5913                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5914    #name,
5915    #inner_ty,
5916    &'a #name,
5917    &'a #inner_ty,
5918    &'a mut #name,
5919    &'a mut #inner_ty,
5920    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5921    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5922> {
5923                                            rust_key_paths::Kp::new(
5924                                                |root: &#name| match root {
5925                                                    #name::#v_ident(inner) => inner.as_deref(),
5926                                                    _ => None,
5927                                                },
5928                                                |root: &mut #name| match root {
5929                                                    #name::#v_ident(inner) => inner.as_mut().and_then(std::sync::Arc::get_mut),
5930                                                    _ => None,
5931                                                },
5932                                            )
5933                                        }
5934                                    });
5935                                }
5936                                (WrapperKind::OptionCow, Some(inner_ty)) => {
5937                                    tokens.extend(quote! {
5938                                        #[inline(always)]
5939                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5940    #name,
5941    #inner_ty,
5942    &'a #name,
5943    &'a #inner_ty,
5944    &'a mut #name,
5945    &'a mut #inner_ty,
5946    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5947    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5948> {
5949                                            rust_key_paths::Kp::new(
5950                                                |root: &#name| match root {
5951                                                    #name::#v_ident(inner) => inner.as_ref().map(|c| c.as_ref()),
5952                                                    _ => None,
5953                                                },
5954                                                |root: &mut #name| match root {
5955                                                    #name::#v_ident(inner) => inner.as_mut().map(|c| c.to_mut()),
5956                                                    _ => None,
5957                                                },
5958                                            )
5959                                        }
5960                                    });
5961                                }
5962                                (WrapperKind::OptionTagged, Some(inner_ty)) => {
5963                                    tokens.extend(quote! {
5964                                        #[inline(always)]
5965                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5966    #name,
5967    #inner_ty,
5968    &'a #name,
5969    &'a #inner_ty,
5970    &'a mut #name,
5971    &'a mut #inner_ty,
5972    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5973    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
5974> {
5975                                            rust_key_paths::Kp::new(
5976                                                |root: &#name| match root {
5977                                                    #name::#v_ident(inner) => inner.as_ref().map(|t| std::ops::Deref::deref(t)),
5978                                                    _ => None,
5979                                                },
5980                                                |root: &mut #name| match root {
5981                                                    #name::#v_ident(inner) => inner.as_mut().map(|t| std::ops::DerefMut::deref_mut(t)),
5982                                                    _ => None,
5983                                                },
5984                                            )
5985                                        }
5986                                    });
5987                                }
5988                                (WrapperKind::OptionReference, Some(inner_ty)) => {
5989                                    tokens.extend(quote! {
5990                                        #[inline(always)]
5991                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
5992    #name,
5993    #inner_ty,
5994    &'a #name,
5995    &'a #inner_ty,
5996    &'a mut #name,
5997    &'a mut #inner_ty,
5998    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
5999    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
6000> {
6001                                            rust_key_paths::Kp::new(
6002                                                |root: &#name| match root {
6003                                                    #name::#v_ident(inner) => inner.as_ref(),
6004                                                    _ => None,
6005                                                },
6006                                                |_root: &mut #name| None,
6007                                            )
6008                                        }
6009                                    });
6010                                }
6011                                (WrapperKind::String, None) => {
6012                                    tokens.extend(quote! {
6013                                        #[inline(always)]
6014                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
6015                                            rust_key_paths::Kp::new(
6016                                                |root: &#name| match root {
6017                                                    #name::#v_ident(inner) => Some(inner),
6018                                                    _ => None,
6019                                                },
6020                                                |root: &mut #name| match root {
6021                                                    #name::#v_ident(inner) => Some(inner),
6022                                                    _ => None,
6023                                                },
6024                                            )
6025                                        }
6026                                    });
6027                                }
6028                                (WrapperKind::OptionString, None) => {
6029                                    tokens.extend(quote! {
6030                                        #[inline(always)]
6031                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, std::string::String, &'a #name, &'a std::string::String, &'a mut #name, &'a mut std::string::String, impl Fn(&'a #name) -> Option<&'a std::string::String>, impl Fn(&'a mut #name) -> Option<&'a mut std::string::String>,>  {
6032                                            rust_key_paths::Kp::new(
6033                                                |root: &#name| match root {
6034                                                    #name::#v_ident(inner) => inner.as_ref(),
6035                                                    _ => None,
6036                                                },
6037                                                |root: &mut #name| match root {
6038                                                    #name::#v_ident(inner) => inner.as_mut(),
6039                                                    _ => None,
6040                                                },
6041                                            )
6042                                        }
6043                                    });
6044                                }
6045                                (WrapperKind::OnceCell, Some(inner_ty)) => {
6046                                    tokens.extend(quote! {
6047                                        #[inline(always)]
6048                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
6049    #name,
6050    #inner_ty,
6051    &'a #name,
6052    &'a #inner_ty,
6053    &'a mut #name,
6054    &'a mut #inner_ty,
6055    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
6056    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
6057> {
6058                                            rust_key_paths::Kp::new(
6059                                                |root: &#name| match root {
6060                                                    #name::#v_ident(inner) => inner.get(),
6061                                                    _ => None,
6062                                                },
6063                                                |_root: &mut #name| None,
6064                                            )
6065                                        }
6066                                    });
6067                                }
6068                                (WrapperKind::Lazy, Some(inner_ty)) => {
6069                                    tokens.extend(quote! {
6070                                        #[inline(always)]
6071                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
6072    #name,
6073    #inner_ty,
6074    &'a #name,
6075    &'a #inner_ty,
6076    &'a mut #name,
6077    &'a mut #inner_ty,
6078    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
6079    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
6080> {
6081                                            rust_key_paths::Kp::new(
6082                                                |root: &#name| match root {
6083                                                    #name::#v_ident(inner) => Some(inner.get()),
6084                                                    _ => None,
6085                                                },
6086                                                |_root: &mut #name| None,
6087                                            )
6088                                        }
6089                                    });
6090                                }
6091                                (WrapperKind::OptionOnceCell, Some(inner_ty)) => {
6092                                    tokens.extend(quote! {
6093                                        #[inline(always)]
6094                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
6095    #name,
6096    #inner_ty,
6097    &'a #name,
6098    &'a #inner_ty,
6099    &'a mut #name,
6100    &'a mut #inner_ty,
6101    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
6102    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
6103> {
6104                                            rust_key_paths::Kp::new(
6105                                                |root: &#name| match root {
6106                                                    #name::#v_ident(inner) => inner.as_ref().and_then(|c| c.get()),
6107                                                    _ => None,
6108                                                },
6109                                                |_root: &mut #name| None,
6110                                            )
6111                                        }
6112                                    });
6113                                }
6114                                (WrapperKind::OptionLazy, Some(inner_ty)) => {
6115                                    tokens.extend(quote! {
6116                                        #[inline(always)]
6117                                        pub fn #snake<'a>() -> rust_key_paths::Kp<
6118    #name,
6119    #inner_ty,
6120    &'a #name,
6121    &'a #inner_ty,
6122    &'a mut #name,
6123    &'a mut #inner_ty,
6124    impl Fn(&'a #name) -> Option<&'a #inner_ty>,
6125    impl Fn(&'a mut #name) -> Option<&'a mut #inner_ty>,
6126> {
6127                                            rust_key_paths::Kp::new(
6128                                                |root: &#name| match root {
6129                                                    #name::#v_ident(inner) => inner.as_ref().map(|c| c.get()),
6130                                                    _ => None,
6131                                                },
6132                                                |_root: &mut #name| None,
6133                                            )
6134                                        }
6135                                    });
6136                                }
6137                                (WrapperKind::Cell, Some(_inner_ty))
6138                                | (WrapperKind::RefCell, Some(_inner_ty))
6139                                | (WrapperKind::PhantomData, Some(_inner_ty))
6140                                | (WrapperKind::Range, Some(_inner_ty))
6141                                | (WrapperKind::OptionCell, Some(_inner_ty))
6142                                | (WrapperKind::OptionPhantomData, Some(_inner_ty))
6143                                | (WrapperKind::OptionRange, Some(_inner_ty)) => {
6144                                    tokens.extend(quote! {
6145                                        #[inline(always)]
6146                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
6147                                            rust_key_paths::Kp::new(
6148                                                |root: &#name| match root {
6149                                                    #name::#v_ident(inner) => Some(inner),
6150                                                    _ => None,
6151                                                },
6152                                                |root: &mut #name| match root {
6153                                                    #name::#v_ident(inner) => Some(inner),
6154                                                    _ => None,
6155                                                },
6156                                            )
6157                                        }
6158                                    });
6159                                }
6160                                (WrapperKind::OptionRefCell, Some(inner_ty)) => {
6161                                    tokens.extend(quote! {
6162                                        #[inline(always)]
6163                                        pub fn #snake() -> rust_key_paths::KpOptionRefCellType<'_, #name, #inner_ty> {
6164                                            rust_key_paths::Kp::new(
6165                                                |root: &#name| match root {
6166                                                    #name::#v_ident(inner) => inner.as_ref().map(|r| r.borrow()),
6167                                                    _ => None,
6168                                                },
6169                                                |root: &mut #name| match root {
6170                                                    #name::#v_ident(inner) => inner.as_ref().map(|r| r.borrow_mut()),
6171                                                    _ => None,
6172                                                },
6173                                            )
6174                                        }
6175                                    });
6176                                }
6177                                (WrapperKind::None, None) => {
6178                                    // Basic type
6179                                    tokens.extend(quote! {
6180                                        #[inline(always)]
6181                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
6182                                            rust_key_paths::Kp::new(
6183                                                |root: &#name| match root {
6184                                                    #name::#v_ident(inner) => Some(inner),
6185                                                    _ => None,
6186                                                },
6187                                                |root: &mut #name| match root {
6188                                                    #name::#v_ident(inner) => Some(inner),
6189                                                    _ => None,
6190                                                },
6191                                            )
6192                                        }
6193                                    });
6194                                }
6195                                _ => {
6196                                    // Other wrapper types - return keypath to field
6197                                    tokens.extend(quote! {
6198                                        #[inline(always)]
6199                                        pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #field_ty, &'a #name, &'a #field_ty, &'a mut #name, &'a mut #field_ty, impl Fn(&'a #name) -> Option<&'a #field_ty>, impl Fn(&'a mut #name) -> Option<&'a mut #field_ty>,> {
6200                                            rust_key_paths::Kp::new(
6201                                                |root: &#name| match root {
6202                                                    #name::#v_ident(inner) => Some(inner),
6203                                                    _ => None,
6204                                                },
6205                                                |root: &mut #name| match root {
6206                                                    #name::#v_ident(inner) => Some(inner),
6207                                                    _ => None,
6208                                                },
6209                                            )
6210                                        }
6211                                    });
6212                                }
6213                            }
6214                        } else {
6215                            // Multi-field tuple variant - return keypath to variant itself
6216                            tokens.extend(quote! {
6217                                #[inline(always)]
6218                                pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #name, &'a #name, &'a #name, &'a mut #name, &'a mut #name, impl Fn(&'a #name) -> Option<&'a #name>, impl Fn(&'a mut #name) -> Option<&'a mut #name>,> {
6219                                    rust_key_paths::Kp::new(
6220                                        |root: &#name| match root {
6221                                            #name::#v_ident(..) => Some(root),
6222                                            _ => None,
6223                                        },
6224                                        |root: &mut #name| match root {
6225                                            #name::#v_ident(..) => Some(root),
6226                                            _ => None,
6227                                        },
6228                                    )
6229                                }
6230                            });
6231                        }
6232                    }
6233                    Fields::Named(_) => {
6234                        // Named field variant - return keypath to variant itself
6235                        tokens.extend(quote! {
6236                            pub fn #snake<'a>() -> rust_key_paths::Kp<#name, #name, &'a #name, &'a #name, &'a mut #name, &'a mut #name, impl Fn(&'a #name) -> Option<&'a #name>, impl Fn(&'a mut #name) -> Option<&'a mut #name>,> {
6237                                rust_key_paths::Kp::new(
6238                                    |root: &#name| match root {
6239                                        #name::#v_ident { .. } => Some(root),
6240                                        _ => None,
6241                                    },
6242                                    |root: &mut #name| match root {
6243                                        #name::#v_ident { .. } => Some(root),
6244                                        _ => None,
6245                                    },
6246                                )
6247                            }
6248                        });
6249                    }
6250                }
6251            }
6252
6253            tokens
6254        }
6255        Data::Union(_) => {
6256            return syn::Error::new(input_span, "Kp derive does not support unions")
6257                .to_compile_error()
6258                .into();
6259        }
6260    };
6261
6262    let expanded = quote! {
6263        impl #name {
6264            #methods
6265        }
6266    };
6267
6268    TokenStream::from(expanded)
6269}
6270
6271/// Derive macro that generates `partial_kps() -> Vec<PKp<Self>>` returning all field/variant keypaths.
6272/// **Requires `#[derive(Kp)]`** so the keypath accessor methods exist.
6273///
6274/// For structs: returns keypaths for each field. For enums: returns keypaths for each variant
6275/// (using the same methods Kp generates, e.g. `some_variant()`).
6276///
6277/// # Example
6278/// ```
6279/// use key_paths_derive::{Kp, Pkp};
6280/// use rust_key_paths::PKp;
6281///
6282/// #[derive(Kp, Pkp)]
6283/// struct Person {
6284///     name: String,
6285///     age: i32,
6286/// }
6287///
6288/// let kps = Person::partial_kps();
6289/// assert_eq!(kps.len(), 2);
6290/// ```
6291#[proc_macro_derive(Pkp)]
6292pub fn derive_partial_keypaths(input: TokenStream) -> TokenStream {
6293    let input = parse_macro_input!(input as DeriveInput);
6294    let name = &input.ident;
6295
6296    let kp_calls = match &input.data {
6297        Data::Struct(data_struct) => match &data_struct.fields {
6298            Fields::Named(fields_named) => {
6299                let calls: Vec<_> = fields_named
6300                    .named
6301                    .iter()
6302                    .filter_map(|f| f.ident.as_ref())
6303                    .map(|field_ident| {
6304                        quote! { rust_key_paths::PKp::new(Self::#field_ident()) }
6305                    })
6306                    .collect();
6307                quote! { #(#calls),* }
6308            }
6309            Fields::Unnamed(unnamed) => {
6310                let calls: Vec<_> = (0..unnamed.unnamed.len())
6311                    .map(|idx| {
6312                        let kp_fn = format_ident!("f{}", idx);
6313                        quote! { rust_key_paths::PKp::new(Self::#kp_fn()) }
6314                    })
6315                    .collect();
6316                quote! { #(#calls),* }
6317            }
6318            Fields::Unit => quote! {},
6319        },
6320        Data::Enum(data_enum) => {
6321            let calls: Vec<_> = data_enum
6322                .variants
6323                .iter()
6324                .map(|variant| {
6325                    let v_ident = &variant.ident;
6326                    let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
6327                    quote! { rust_key_paths::PKp::new(Self::#snake()) }
6328                })
6329                .collect();
6330            quote! { #(#calls),* }
6331        }
6332        Data::Union(_) => {
6333            return syn::Error::new(input.ident.span(), "Pkp derive does not support unions")
6334                .to_compile_error()
6335                .into();
6336        }
6337    };
6338
6339    let expanded = quote! {
6340        impl #name {
6341            /// Returns a vec of all field keypaths as partial keypaths (type-erased).
6342            #[inline(always)]
6343            pub fn partial_kps() -> Vec<rust_key_paths::PKp<#name>> {
6344                vec![#kp_calls]
6345            }
6346        }
6347    };
6348
6349    TokenStream::from(expanded)
6350}
6351
6352/// Derive macro that generates `any_kps() -> Vec<AKp>` returning all field/variant keypaths as any keypaths.
6353/// **Requires `#[derive(Kp)]`** so the keypath accessor methods exist.
6354/// AKp type-erases both Root and Value, enabling heterogeneous collections of keypaths.
6355///
6356/// For structs: returns keypaths for each field. For enums: returns keypaths for each variant
6357/// (using the same methods Kp generates, e.g. `some_variant()`).
6358///
6359/// # Example
6360/// ```
6361/// use key_paths_derive::{Kp, Akp};
6362/// use rust_key_paths::AKp;
6363///
6364/// #[derive(Kp, Akp)]
6365/// struct Person {
6366///     name: String,
6367///     age: i32,
6368/// }
6369///
6370/// let kps = Person::any_kps();
6371/// assert_eq!(kps.len(), 2);
6372/// let person = Person { name: "Akash".into(), age: 30 };
6373/// let name: Option<&String> = kps[0].get(&person as &dyn std::any::Any).and_then(|v| v.downcast_ref());
6374/// assert_eq!(name, Some(&"Akash".to_string()));
6375/// ```
6376#[proc_macro_derive(Akp)]
6377pub fn derive_any_keypaths(input: TokenStream) -> TokenStream {
6378    let input = parse_macro_input!(input as DeriveInput);
6379    let name = &input.ident;
6380
6381    let kp_calls = match &input.data {
6382        Data::Struct(data_struct) => match &data_struct.fields {
6383            Fields::Named(fields_named) => {
6384                let calls: Vec<_> = fields_named
6385                    .named
6386                    .iter()
6387                    .filter_map(|f| f.ident.as_ref())
6388                    .map(|field_ident| {
6389                        quote! { rust_key_paths::AKp::new(Self::#field_ident()) }
6390                    })
6391                    .collect();
6392                quote! { #(#calls),* }
6393            }
6394            Fields::Unnamed(unnamed) => {
6395                let calls: Vec<_> = (0..unnamed.unnamed.len())
6396                    .map(|idx| {
6397                        let kp_fn = format_ident!("f{}", idx);
6398                        quote! { rust_key_paths::AKp::new(Self::#kp_fn()) }
6399                    })
6400                    .collect();
6401                quote! { #(#calls),* }
6402            }
6403            Fields::Unit => quote! {},
6404        },
6405        Data::Enum(data_enum) => {
6406            let calls: Vec<_> = data_enum
6407                .variants
6408                .iter()
6409                .map(|variant| {
6410                    let v_ident = &variant.ident;
6411                    let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
6412                    quote! { rust_key_paths::AKp::new(Self::#snake()) }
6413                })
6414                .collect();
6415            quote! { #(#calls),* }
6416        }
6417        Data::Union(_) => {
6418            return syn::Error::new(input.ident.span(), "Akp derive does not support unions")
6419                .to_compile_error()
6420                .into();
6421        }
6422    };
6423
6424    let expanded = quote! {
6425        impl #name {
6426            /// Returns a vec of all field keypaths as any keypaths (fully type-erased).
6427            #[inline(always)]
6428            pub fn any_kps() -> Vec<rust_key_paths::AKp> {
6429                vec![#kp_calls]
6430            }
6431        }
6432    };
6433
6434    TokenStream::from(expanded)
6435}