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