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