Skip to main content

key_paths_derive/
lib.rs

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