key_paths_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::{format_ident, quote};
3use syn::{Data, DeriveInput, Fields, Type, parse_macro_input};
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    // Synchronization primitives
23    Mutex,
24    RwLock,
25    // Reference counting with weak references
26    Weak,
27    // String types
28    String,
29    OsString,
30    PathBuf,
31    // Nested container support
32    OptionBox,
33    OptionRc,
34    OptionArc,
35    BoxOption,
36    RcOption,
37    ArcOption,
38    VecOption,
39    OptionVec,
40    HashMapOption,
41    OptionHashMap,
42    // Arc with synchronization primitives
43    ArcMutex,
44    ArcRwLock,
45    // Tagged types
46    Tagged,
47}
48
49#[proc_macro_derive(Keypaths)]
50pub fn derive_keypaths(input: TokenStream) -> TokenStream {
51    let input = parse_macro_input!(input as DeriveInput);
52    let name = input.ident;
53
54    let methods = match input.data {
55        Data::Struct(data_struct) => match data_struct.fields {
56            Fields::Named(fields_named) => {
57                let mut tokens = proc_macro2::TokenStream::new();
58                for field in fields_named.named.iter() {
59                    let field_ident = field.ident.as_ref().unwrap();
60                    let ty = &field.ty;
61
62                    let r_fn = format_ident!("{}_r", field_ident);
63                    let w_fn = format_ident!("{}_w", field_ident);
64                    let fr_fn = format_ident!("{}_fr", field_ident);
65                    let fw_fn = format_ident!("{}_fw", field_ident);
66                    let fr_at_fn = format_ident!("{}_fr_at", field_ident);
67                    let fw_at_fn = format_ident!("{}_fw_at", field_ident);
68                    // Owned keypath method names
69                    let o_fn = format_ident!("{}_o", field_ident);
70                    let fo_fn = format_ident!("{}_fo", field_ident);
71
72                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
73
74                    match (kind, inner_ty) {
75                        (WrapperKind::Option, Some(inner_ty)) => {
76                            tokens.extend(quote! {
77                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
78                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
79                                }
80                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
81                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
82                                }
83                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
84                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref())
85                                }
86                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
87                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.as_mut())
88                                }
89                                // Owned keypath methods
90                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
91                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
92                                }
93                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
94                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident)
95                                }
96                            });
97                        }
98                        (WrapperKind::Vec, Some(inner_ty)) => {
99                            tokens.extend(quote! {
100                                pub fn #fr_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
101                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(index))
102                                }
103                                pub fn #fw_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
104                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(index))
105                                }
106                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
107                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
108                                }
109                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
110                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
111                                }
112                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
113                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.first())
114                                }
115                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
116                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.first_mut())
117                                }
118                                // Owned keypath methods
119                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
120                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
121                                }
122                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
123                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_iter().next())
124                                }
125                            });
126                        }
127                        (WrapperKind::HashMap, Some(inner_ty)) => {
128                            tokens.extend(quote! {
129                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
130                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
131                                }
132                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
133                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
134                                }
135                                pub fn #fr_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
136                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key))
137                                }
138                                pub fn #fw_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
139                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key))
140                                }
141                                pub fn #fr_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
142                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key))
143                                }
144                                pub fn #fw_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
145                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key))
146                                }
147                                // Owned keypath methods
148                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
149                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
150                                }
151                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
152                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_values().next())
153                                }
154                            });
155                        }
156                        (WrapperKind::Box, Some(inner_ty)) => {
157                            tokens.extend(quote! {
158                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
159                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
160                                }
161                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
162                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut *s.#field_ident)
163                                }
164                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
165                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#field_ident))
166                                }
167                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
168                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut *s.#field_ident))
169                                }
170                                // Owned keypath methods
171                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
172                                    key_paths_core::KeyPaths::owned(|s: #name| *s.#field_ident)
173                                }
174                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
175                                    key_paths_core::KeyPaths::failable_owned(|s: #name| Some(*s.#field_ident))
176                                }
177                            });
178                        }
179                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
180                            tokens.extend(quote! {
181                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
182                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
183                                }
184                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
185                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#field_ident))
186                                }
187                                // Owned keypath methods
188                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
189                                    key_paths_core::KeyPaths::owned(|s: #name| (*s.#field_ident).clone())
190                                }
191                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
192                                    key_paths_core::KeyPaths::failable_owned(|s: #name| Some((*s.#field_ident).clone()))
193                                }
194                            });
195                        }
196                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
197                            tokens.extend(quote! {
198                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
199                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
200                                }
201                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
202                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
203                                }
204                                // Owned keypath methods
205                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
206                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
207                                }
208                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
209                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_values().next())
210                                }
211                                // Note: Key-based access methods for BTreeMap require the exact key type
212                                // For now, we'll skip generating these methods to avoid generic constraint issues
213                            });
214                        }
215                        (WrapperKind::HashSet, Some(inner_ty)) => {
216                            tokens.extend(quote! {
217                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
218                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
219                                }
220                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
221                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
222                                }
223                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
224                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.iter().next())
225                                }
226                                // Owned keypath methods
227                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
228                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
229                                }
230                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
231                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_iter().next())
232                                }
233                            });
234                        }
235                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
236                            tokens.extend(quote! {
237                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
238                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
239                                }
240                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
241                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
242                                }
243                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
244                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.iter().next())
245                                }
246                                // Owned keypath methods
247                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
248                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
249                                }
250                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
251                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_iter().next())
252                                }
253                            });
254                        }
255                        (WrapperKind::VecDeque, Some(inner_ty)) => {
256                            tokens.extend(quote! {
257                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
258                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
259                                }
260                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
261                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
262                                }
263                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
264                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.front())
265                                }
266                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
267                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.front_mut())
268                                }
269                                pub fn #fr_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
270                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(index))
271                                }
272                                pub fn #fw_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
273                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(index))
274                                }
275                                // Owned keypath methods
276                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
277                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
278                                }
279                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
280                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_iter().next())
281                                }
282                            });
283                        }
284                        (WrapperKind::LinkedList, Some(inner_ty)) => {
285                            tokens.extend(quote! {
286                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
287                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
288                                }
289                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
290                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
291                                }
292                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
293                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.front())
294                                }
295                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
296                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.front_mut())
297                                }
298                                // Owned keypath methods
299                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
300                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
301                                }
302                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
303                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_iter().next())
304                                }
305                            });
306                        }
307                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
308                            tokens.extend(quote! {
309                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
310                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
311                                }
312                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
313                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
314                                }
315                                // Owned keypath methods
316                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
317                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
318                                }
319                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
320                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.into_iter().next())
321                                }
322                                // Note: BinaryHeap peek() returns &T, but we need &inner_ty
323                                // For now, we'll skip failable methods for BinaryHeap to avoid type issues
324                            });
325                        }
326                        (WrapperKind::Result, Some(inner_ty)) => {
327                            tokens.extend(quote! {
328                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
329                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
330                                }
331                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
332                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
333                                }
334                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
335                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().ok())
336                                }
337                                // Note: Result<T, E> doesn't support failable_writable for inner type
338                                // Only providing container-level writable access
339                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
340                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
341                                }
342                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
343                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#field_ident.ok())
344                                }
345                            });
346                        }
347                        (WrapperKind::Mutex, Some(inner_ty)) => {
348                            tokens.extend(quote! {
349                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
350                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
351                                }
352                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
353                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
354                                }
355                                // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
356                                // Only providing container-level access
357                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
358                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
359                                }
360                            });
361                        }
362                        (WrapperKind::RwLock, Some(inner_ty)) => {
363                            tokens.extend(quote! {
364                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
365                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
366                                }
367                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
368                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
369                                }
370                                // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
371                                // Only providing container-level access
372                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
373                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
374                                }
375                            });
376                        }
377                        (WrapperKind::ArcMutex, Some(inner_ty)) => {
378                            tokens.extend(quote! {
379                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
380                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
381                                }
382                                // Note: Arc<Mutex<T>> doesn't support writable access (Arc is immutable)
383                                // Note: Arc<Mutex<T>> doesn't support direct access to inner type due to lifetime constraints
384                                // Only providing container-level access
385                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
386                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
387                                }
388                            });
389                        }
390                        (WrapperKind::ArcRwLock, Some(inner_ty)) => {
391                            tokens.extend(quote! {
392                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
393                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
394                                }
395                                // Note: Arc<RwLock<T>> doesn't support writable access (Arc is immutable)
396                                // Note: Arc<RwLock<T>> doesn't support direct access to inner type due to lifetime constraints
397                                // Only providing container-level access
398                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
399                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
400                                }
401                            });
402                        }
403                        (WrapperKind::Weak, Some(inner_ty)) => {
404                            tokens.extend(quote! {
405                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
406                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
407                                }
408                                // Note: Weak<T> doesn't support writable access (it's immutable)
409                                // Note: Weak<T> doesn't support direct access to inner type due to lifetime constraints
410                                // Only providing container-level access
411                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
412                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
413                                }
414                            });
415                        }
416                        // Nested container combinations - COMMENTED OUT FOR NOW
417                        // TODO: Fix type mismatch issues in nested combinations
418                        /*
419                        (WrapperKind::OptionBox, Some(inner_ty)) => {
420                            tokens.extend(quote! {
421                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
422                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
423                                }
424                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
425                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
426                                }
427                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
428                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().map(|b| &**b))
429                                }
430                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
431                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.as_mut().map(|b| &mut **b))
432                                }
433                            });
434                        }
435                        (WrapperKind::OptionRc, Some(inner_ty)) => {
436                            tokens.extend(quote! {
437                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
438                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
439                                }
440                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
441                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().map(|r| &**r))
442                                }
443                            });
444                        }
445                        (WrapperKind::OptionArc, Some(inner_ty)) => {
446                            tokens.extend(quote! {
447                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
448                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
449                                }
450                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
451                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().map(|a| &**a))
452                                }
453                            });
454                        }
455                        (WrapperKind::BoxOption, Some(inner_ty)) => {
456                            tokens.extend(quote! {
457                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
458                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
459                                }
460                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
461                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut *s.#field_ident)
462                                }
463                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
464                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| (*s.#field_ident).as_ref())
465                                }
466                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
467                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| (*s.#field_ident).as_mut())
468                                }
469                            });
470                        }
471                        (WrapperKind::RcOption, Some(inner_ty)) => {
472                            tokens.extend(quote! {
473                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
474                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
475                                }
476                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
477                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| (*s.#field_ident).as_ref())
478                                }
479                            });
480                        }
481                        (WrapperKind::ArcOption, Some(inner_ty)) => {
482                            tokens.extend(quote! {
483                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
484                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
485                                }
486                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
487                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| (*s.#field_ident).as_ref())
488                                }
489                            });
490                        }
491                        (WrapperKind::VecOption, Some(inner_ty)) => {
492                            tokens.extend(quote! {
493                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
494                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
495                                }
496                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
497                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
498                                }
499                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
500                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.first().and_then(|opt| opt.as_ref()))
501                                }
502                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
503                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.first_mut().and_then(|opt| opt.as_mut()))
504                                }
505                                pub fn #fr_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
506                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(index).and_then(|opt| opt.as_ref()))
507                                }
508                                pub fn #fw_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
509                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(index).and_then(|opt| opt.as_mut()))
510                                }
511                            });
512                        }
513                        (WrapperKind::OptionVec, Some(inner_ty)) => {
514                            tokens.extend(quote! {
515                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
516                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
517                                }
518                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
519                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
520                                }
521                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
522                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().and_then(|v| v.first()))
523                                }
524                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
525                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.as_mut().and_then(|v| v.first_mut()))
526                                }
527                                pub fn #fr_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
528                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.as_ref().and_then(|v| v.get(index)))
529                                }
530                                pub fn #fw_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
531                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.as_mut().and_then(|v| v.get_mut(index)))
532                                }
533                            });
534                        }
535                        (WrapperKind::HashMapOption, Some(inner_ty)) => {
536                            tokens.extend(quote! {
537                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
538                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
539                                }
540                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
541                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
542                                }
543                                pub fn #fr_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
544                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key).and_then(|opt| opt.as_ref()))
545                                }
546                                pub fn #fw_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
547                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key).and_then(|opt| opt.as_mut()))
548                                }
549                                pub fn #fr_at_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
550                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key).and_then(|opt| opt.as_ref()))
551                                }
552                                pub fn #fw_at_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
553                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key).and_then(|opt| opt.as_mut()))
554                                }
555                            });
556                        }
557                        (WrapperKind::OptionHashMap, Some(inner_ty)) => {
558                            tokens.extend(quote! {
559                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
560                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
561                                }
562                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
563                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
564                                }
565                                pub fn #fr_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
566                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.as_ref().and_then(|m| m.get(&key)))
567                                }
568                                pub fn #fw_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
569                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.as_mut().and_then(|m| m.get_mut(&key)))
570                                }
571                                pub fn #fr_at_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
572                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.as_ref().and_then(|m| m.get(&key)))
573                                }
574                                pub fn #fw_at_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
575                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.as_mut().and_then(|m| m.get_mut(&key)))
576                                }
577                            });
578                        }
579                        */
580                        (WrapperKind::None, None) => {
581                            tokens.extend(quote! {
582                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
583                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
584                                }
585                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
586                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
587                                }
588                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #ty> {
589                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&s.#field_ident))
590                                }
591                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #ty> {
592                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut s.#field_ident))
593                                }
594                                // Owned keypath methods
595                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
596                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
597                                }
598                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #ty> {
599                                    key_paths_core::KeyPaths::failable_owned(|s: #name| Some(s.#field_ident))
600                                }
601                            });
602                        }
603                        _ => {
604                            tokens.extend(quote! {
605                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
606                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
607                                }
608                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
609                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
610                                }
611                                // Owned keypath methods
612                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
613                                    key_paths_core::KeyPaths::owned(|s: #name| s.#field_ident)
614                                }
615                            });
616                        }
617                    }
618                }
619                tokens
620            }
621            Fields::Unnamed(unnamed) => {
622                let mut tokens = proc_macro2::TokenStream::new();
623                for (idx, field) in unnamed.unnamed.iter().enumerate() {
624                    let idx_lit = syn::Index::from(idx);
625                    let ty = &field.ty;
626
627                    let r_fn = format_ident!("f{}_r", idx);
628                    let w_fn = format_ident!("f{}_w", idx);
629                    let fr_fn = format_ident!("f{}_fr", idx);
630                    let fw_fn = format_ident!("f{}_fw", idx);
631                    let fr_at_fn = format_ident!("f{}_fr_at", idx);
632                    let fw_at_fn = format_ident!("f{}_fw_at", idx);
633                    // Owned keypath method names
634                    let o_fn = format_ident!("f{}_o", idx);
635                    let fo_fn = format_ident!("f{}_fo", idx);
636
637                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
638
639                    match (kind, inner_ty) {
640                        (WrapperKind::Option, Some(inner_ty)) => {
641                            tokens.extend(quote! {
642                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
643                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
644                                }
645                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
646                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
647                                }
648                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
649                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref())
650                                }
651                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
652                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.as_mut())
653                                }
654                                // Owned keypath methods
655                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
656                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
657                                }
658                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
659                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit)
660                                }
661                            });
662                        }
663                        (WrapperKind::Vec, Some(inner_ty)) => {
664                            tokens.extend(quote! {
665                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
666                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
667                                }
668                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
669                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
670                                }
671                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
672                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.first())
673                                }
674                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
675                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.first_mut())
676                                }
677                                pub fn #fr_at_fn(index: &'static usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
678                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.get(*index))
679                                }
680                                pub fn #fw_at_fn(index: &'static usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
681                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.get_mut(*index))
682                                }
683                                // Owned keypath methods
684                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
685                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
686                                }
687                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
688                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_iter().next())
689                                }
690                            });
691                        }
692                        (WrapperKind::HashMap, Some(inner_ty)) => {
693                            tokens.extend(quote! {
694                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
695                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
696                                }
697                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
698                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
699                                }
700                                pub fn #fr_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
701                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key))
702                                }
703                                pub fn #fw_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
704                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key))
705                                }
706                                pub fn #fr_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
707                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key))
708                                }
709                                pub fn #fw_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
710                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key))
711                                }
712                                // Owned keypath methods
713                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
714                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
715                                }
716                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
717                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_values().next())
718                                }
719                            });
720                        }
721                        (WrapperKind::Box, Some(inner_ty)) => {
722                            tokens.extend(quote! {
723                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
724                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
725                                }
726                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
727                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut *s.#idx_lit)
728                                }
729                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
730                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#idx_lit))
731                                }
732                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
733                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut *s.#idx_lit))
734                                }
735                                // Owned keypath methods
736                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
737                                    key_paths_core::KeyPaths::owned(|s: #name| *s.#idx_lit)
738                                }
739                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
740                                    key_paths_core::KeyPaths::failable_owned(|s: #name| Some(*s.#idx_lit))
741                                }
742                            });
743                        }
744                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
745                            tokens.extend(quote! {
746                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
747                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
748                                }
749                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
750                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#idx_lit))
751                                }
752                                // Owned keypath methods
753                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
754                                    key_paths_core::KeyPaths::owned(|s: #name| (*s.#idx_lit).clone())
755                                }
756                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
757                                    key_paths_core::KeyPaths::failable_owned(|s: #name| Some((*s.#idx_lit).clone()))
758                                }
759                            });
760                        }
761                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
762                            tokens.extend(quote! {
763                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
764                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
765                                }
766                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
767                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
768                                }
769                                // Owned keypath methods
770                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
771                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
772                                }
773                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
774                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_values().next())
775                                }
776                                // Note: Key-based access methods for BTreeMap require the exact key type
777                                // For now, we'll skip generating these methods to avoid generic constraint issues
778                            });
779                        }
780                        (WrapperKind::HashSet, Some(inner_ty)) => {
781                            tokens.extend(quote! {
782                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
783                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
784                                }
785                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
786                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
787                                }
788                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
789                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.iter().next())
790                                }
791                                // Owned keypath methods
792                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
793                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
794                                }
795                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
796                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_iter().next())
797                                }
798                            });
799                        }
800                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
801                            tokens.extend(quote! {
802                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
803                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
804                                }
805                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
806                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
807                                }
808                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
809                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.iter().next())
810                                }
811                                // Owned keypath methods
812                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
813                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
814                                }
815                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
816                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_iter().next())
817                                }
818                            });
819                        }
820                        (WrapperKind::VecDeque, Some(inner_ty)) => {
821                            tokens.extend(quote! {
822                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
823                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
824                                }
825                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
826                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
827                                }
828                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
829                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.front())
830                                }
831                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
832                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.front_mut())
833                                }
834                                // Owned keypath methods
835                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
836                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
837                                }
838                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
839                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_iter().next())
840                                }
841                            });
842                        }
843                        (WrapperKind::LinkedList, Some(inner_ty)) => {
844                            tokens.extend(quote! {
845                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
846                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
847                                }
848                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
849                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
850                                }
851                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
852                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.front())
853                                }
854                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
855                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.front_mut())
856                                }
857                                // Owned keypath methods
858                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
859                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
860                                }
861                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
862                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_iter().next())
863                                }
864                            });
865                        }
866                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
867                            tokens.extend(quote! {
868                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
869                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
870                                }
871                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
872                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
873                                }
874                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
875                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.peek())
876                                }
877                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
878                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.peek_mut().map(|v| &mut **v))
879                                }
880                                // Owned keypath methods
881                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
882                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
883                                }
884                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
885                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.into_iter().next())
886                                }
887                            });
888                        }
889                        (WrapperKind::Result, Some(inner_ty)) => {
890                            tokens.extend(quote! {
891                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
892                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
893                                }
894                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
895                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
896                                }
897                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
898                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().ok())
899                                }
900                                // Note: Result<T, E> doesn't support failable_writable for inner type
901                                // Only providing container-level writable access
902                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
903                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
904                                }
905                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
906                                    key_paths_core::KeyPaths::failable_owned(|s: #name| s.#idx_lit.ok())
907                                }
908                            });
909                        }
910                        (WrapperKind::Mutex, Some(inner_ty)) => {
911                            tokens.extend(quote! {
912                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
913                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
914                                }
915                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
916                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
917                                }
918                                // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
919                                // Only providing container-level access
920                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
921                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
922                                }
923                            });
924                        }
925                        (WrapperKind::RwLock, Some(inner_ty)) => {
926                            tokens.extend(quote! {
927                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
928                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
929                                }
930                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
931                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
932                                }
933                                // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
934                                // Only providing container-level access
935                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
936                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
937                                }
938                            });
939                        }
940                        (WrapperKind::Weak, Some(inner_ty)) => {
941                            tokens.extend(quote! {
942                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
943                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
944                                }
945                                // Note: Weak<T> doesn't support writable access (it's immutable)
946                                // Note: Weak<T> doesn't support direct access to inner type due to lifetime constraints
947                                // Only providing container-level access
948                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
949                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
950                                }
951                            });
952                        }
953                        // Nested container combinations for tuple structs - COMMENTED OUT FOR NOW
954                        /*
955                        (WrapperKind::OptionBox, Some(inner_ty)) => {
956                            tokens.extend(quote! {
957                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
958                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
959                                }
960                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
961                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
962                                }
963                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
964                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().map(|b| &**b))
965                                }
966                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
967                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.as_mut().map(|b| &mut **b))
968                                }
969                            });
970                        }
971                        (WrapperKind::OptionRc, Some(inner_ty)) => {
972                            tokens.extend(quote! {
973                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
974                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
975                                }
976                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
977                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().map(|r| &**r))
978                                }
979                            });
980                        }
981                        (WrapperKind::OptionArc, Some(inner_ty)) => {
982                            tokens.extend(quote! {
983                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
984                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
985                                }
986                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
987                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().map(|a| &**a))
988                                }
989                            });
990                        }
991                        (WrapperKind::BoxOption, Some(inner_ty)) => {
992                            tokens.extend(quote! {
993                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
994                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
995                                }
996                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
997                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut *s.#idx_lit)
998                                }
999                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1000                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| (*s.#idx_lit).as_ref())
1001                                }
1002                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1003                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| (*s.#idx_lit).as_mut())
1004                                }
1005                            });
1006                        }
1007                        (WrapperKind::RcOption, Some(inner_ty)) => {
1008                            tokens.extend(quote! {
1009                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1010                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
1011                                }
1012                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1013                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| (*s.#idx_lit).as_ref())
1014                                }
1015                            });
1016                        }
1017                        (WrapperKind::ArcOption, Some(inner_ty)) => {
1018                            tokens.extend(quote! {
1019                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1020                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
1021                                }
1022                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1023                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| (*s.#idx_lit).as_ref())
1024                                }
1025                            });
1026                        }
1027                        (WrapperKind::VecOption, Some(inner_ty)) => {
1028                            tokens.extend(quote! {
1029                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1030                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
1031                                }
1032                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1033                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1034                                }
1035                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1036                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.first().and_then(|opt| opt.as_ref()))
1037                                }
1038                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1039                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.first_mut().and_then(|opt| opt.as_mut()))
1040                                }
1041                            });
1042                        }
1043                        (WrapperKind::OptionVec, Some(inner_ty)) => {
1044                            tokens.extend(quote! {
1045                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1046                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
1047                                }
1048                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1049                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1050                                }
1051                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1052                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().and_then(|v| v.first()))
1053                                }
1054                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1055                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.as_mut().and_then(|v| v.first_mut()))
1056                                }
1057                            });
1058                        }
1059                        (WrapperKind::HashMapOption, Some(inner_ty)) => {
1060                            tokens.extend(quote! {
1061                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1062                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
1063                                }
1064                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1065                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1066                                }
1067                                pub fn #fr_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1068                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key).and_then(|opt| opt.as_ref()))
1069                                }
1070                                pub fn #fw_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1071                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key).and_then(|opt| opt.as_mut()))
1072                                }
1073                            });
1074                        }
1075                        (WrapperKind::OptionHashMap, Some(inner_ty)) => {
1076                            tokens.extend(quote! {
1077                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1078                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
1079                                }
1080                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1081                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1082                                }
1083                                pub fn #fr_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1084                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.as_ref().and_then(|m| m.get(&key)))
1085                                }
1086                                pub fn #fw_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1087                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.as_mut().and_then(|m| m.get_mut(&key)))
1088                                }
1089                            });
1090                        }
1091                        */
1092                        (WrapperKind::None, None) => {
1093                            tokens.extend(quote! {
1094                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1095                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
1096                                }
1097                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1098                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1099                                }
1100                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1101                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&s.#idx_lit))
1102                                }
1103                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1104                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut s.#idx_lit))
1105                                }
1106                                // Owned keypath methods
1107                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1108                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
1109                                }
1110                                pub fn #fo_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1111                                    key_paths_core::KeyPaths::failable_owned(|s: #name| Some(s.#idx_lit))
1112                                }
1113                            });
1114                        }
1115                        _ => {
1116                            tokens.extend(quote! {
1117                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1118                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
1119                                }
1120                                // Owned keypath methods
1121                                pub fn #o_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1122                                    key_paths_core::KeyPaths::owned(|s: #name| s.#idx_lit)
1123                                }
1124                            });
1125                        }
1126                    }
1127                }
1128                tokens
1129            }
1130            _ => quote! {
1131                compile_error!("Keypaths derive supports only structs with named or unnamed fields");
1132            },
1133        },
1134        Data::Enum(data_enum) => {
1135            let mut tokens = proc_macro2::TokenStream::new();
1136            for variant in data_enum.variants.iter() {
1137                let v_ident = &variant.ident;
1138                let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
1139                let r_fn = format_ident!("{}_case_r", snake);
1140                let w_fn = format_ident!("{}_case_w", snake);
1141                let _fr_fn = format_ident!("{}_case_fr", snake);
1142                let _fw_fn = format_ident!("{}_case_fw", snake);
1143                let fr_at_fn = format_ident!("{}_case_fr_at", snake);
1144                let fw_at_fn = format_ident!("{}_case_fw_at", snake);
1145
1146                match &variant.fields {
1147                    Fields::Unit => {
1148                        tokens.extend(quote! {
1149                            pub fn #r_fn() -> key_paths_core::KeyPaths<#name, ()> {
1150                                static UNIT: () = ();
1151                                key_paths_core::KeyPaths::readable_enum(
1152                                    |_| #name::#v_ident,
1153                                    |e: &#name| match e { #name::#v_ident => Some(&UNIT), _ => None }
1154                                )
1155                            }
1156                        });
1157                    }
1158                    Fields::Unnamed(unnamed) if unnamed.unnamed.len() == 1 => {
1159                        let field_ty = &unnamed.unnamed.first().unwrap().ty;
1160                        let (kind, inner_ty_opt) = extract_wrapper_inner_type(field_ty);
1161
1162                        match (kind, inner_ty_opt) {
1163                            (WrapperKind::Option, Some(inner_ty)) => {
1164                                tokens.extend(quote! {
1165                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1166                                        key_paths_core::KeyPaths::readable_enum(
1167                                            #name::#v_ident,
1168                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref(), _ => None }
1169                                        )
1170                                    }
1171                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1172                                        key_paths_core::KeyPaths::writable_enum(
1173                                            #name::#v_ident,
1174                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref(), _ => None },
1175                                            |e: &mut #name| match e { #name::#v_ident(v) => v.as_mut(), _ => None },
1176                                        )
1177                                    }
1178                                });
1179                            }
1180                            (WrapperKind::Vec, Some(inner_ty)) => {
1181                                tokens.extend(quote! {
1182                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1183                                        key_paths_core::KeyPaths::readable_enum(
1184                                            #name::#v_ident,
1185                                            |e: &#name| match e { #name::#v_ident(v) => v.first(), _ => None }
1186                                        )
1187                                    }
1188                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1189                                        key_paths_core::KeyPaths::writable_enum(
1190                                            #name::#v_ident,
1191                                            |e: &#name| match e { #name::#v_ident(v) => v.first(), _ => None },
1192                                            |e: &mut #name| match e { #name::#v_ident(v) => v.first_mut(), _ => None },
1193                                        )
1194                                    }
1195                                    pub fn #fr_at_fn(index: &'static usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1196                                        key_paths_core::KeyPaths::readable_enum(
1197                                            #name::#v_ident,
1198                                            |e: &#name| match e { #name::#v_ident(v) => v.get(*index), _ => None }
1199                                        )
1200                                    }
1201                                    pub fn #fw_at_fn(index: &'static usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1202                                        key_paths_core::KeyPaths::writable_enum(
1203                                            #name::#v_ident,
1204                                            |e: &#name| match e { #name::#v_ident(v) => v.get(*index), _ => None },
1205                                            |e: &mut #name| match e { #name::#v_ident(v) => v.get_mut(*index), _ => None },
1206                                        )
1207                                    }
1208                                });
1209                            }
1210                        (WrapperKind::HashMap, Some(inner_ty)) => {
1211                            tokens.extend(quote! {
1212                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1213                                        key_paths_core::KeyPaths::readable_enum(
1214                                            #name::#v_ident,
1215                                            |e: &#name| match e { #name::#v_ident(v) => v.first().map(|(_, v)| v), _ => None }
1216                                        )
1217                                    }
1218                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1219                                        key_paths_core::KeyPaths::writable_enum(
1220                                            #name::#v_ident,
1221                                            |e: &#name| match e { #name::#v_ident(v) => v.first().map(|(_, v)| v), _ => None },
1222                                            |e: &mut #name| match e { #name::#v_ident(v) => v.first_mut().map(|(_, v)| v), _ => None },
1223                                        )
1224                                    }
1225                                    pub fn #fr_at_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: &'static K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1226                                        key_paths_core::KeyPaths::readable_enum(
1227                                            #name::#v_ident,
1228                                            |e: &#name| match e { #name::#v_ident(v) => v.get(key), _ => None }
1229                                        )
1230                                    }
1231                                    pub fn #fw_at_fn<K: ::std::hash::Hash + ::std::cmp::Eq + 'static>(key: &'static K) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1232                                        key_paths_core::KeyPaths::writable_enum(
1233                                            #name::#v_ident,
1234                                            |e: &#name| match e { #name::#v_ident(v) => v.get(key), _ => None },
1235                                            |e: &mut #name| match e { #name::#v_ident(v) => v.get_mut(key), _ => None },
1236                                        )
1237                                    }
1238                                });
1239                            }
1240                            (WrapperKind::Box, Some(inner_ty)) => {
1241                                tokens.extend(quote! {
1242                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1243                                        key_paths_core::KeyPaths::readable_enum(
1244                                            #name::#v_ident,
1245                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None }
1246                                        )
1247                                    }
1248                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1249                                        key_paths_core::KeyPaths::writable_enum(
1250                                            #name::#v_ident,
1251                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None },
1252                                            |e: &mut #name| match e { #name::#v_ident(v) => Some(&mut *v), _ => None },
1253                                        )
1254                                    }
1255                                });
1256                            }
1257                            (WrapperKind::Rc, Some(inner_ty))
1258                            | (WrapperKind::Arc, Some(inner_ty)) => {
1259                                tokens.extend(quote! {
1260                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1261                                        key_paths_core::KeyPaths::readable_enum(
1262                                            #name::#v_ident,
1263                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None }
1264                                        )
1265                                    }
1266                                });
1267                            }
1268                            (WrapperKind::BTreeMap, Some(inner_ty)) => {
1269                                tokens.extend(quote! {
1270                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1271                                        key_paths_core::KeyPaths::readable_enum(
1272                                            #name::#v_ident,
1273                                            |e: &#name| match e { #name::#v_ident(v) => v.first().map(|(_, v)| v), _ => None }
1274                                        )
1275                                    }
1276                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1277                                        key_paths_core::KeyPaths::writable_enum(
1278                                            #name::#v_ident,
1279                                            |e: &#name| match e { #name::#v_ident(v) => v.first().map(|(_, v)| v), _ => None },
1280                                            |e: &mut #name| match e { #name::#v_ident(v) => v.first_mut().map(|(_, v)| v), _ => None },
1281                                        )
1282                                    }
1283                                });
1284                            }
1285                            (WrapperKind::HashSet, Some(inner_ty)) => {
1286                                tokens.extend(quote! {
1287                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1288                                        key_paths_core::KeyPaths::readable_enum(
1289                                            #name::#v_ident,
1290                                            |e: &#name| match e { #name::#v_ident(v) => v.iter().next(), _ => None }
1291                                        )
1292                                    }
1293                                });
1294                            }
1295                            (WrapperKind::BTreeSet, Some(inner_ty)) => {
1296                                tokens.extend(quote! {
1297                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1298                                        key_paths_core::KeyPaths::readable_enum(
1299                                            #name::#v_ident,
1300                                            |e: &#name| match e { #name::#v_ident(v) => v.iter().next(), _ => None }
1301                                        )
1302                                    }
1303                                });
1304                            }
1305                            (WrapperKind::VecDeque, Some(inner_ty)) => {
1306                                tokens.extend(quote! {
1307                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1308                                        key_paths_core::KeyPaths::readable_enum(
1309                                            #name::#v_ident,
1310                                            |e: &#name| match e { #name::#v_ident(v) => v.front(), _ => None }
1311                                        )
1312                                    }
1313                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1314                                        key_paths_core::KeyPaths::writable_enum(
1315                                            #name::#v_ident,
1316                                            |e: &#name| match e { #name::#v_ident(v) => v.front(), _ => None },
1317                                            |e: &mut #name| match e { #name::#v_ident(v) => v.front_mut(), _ => None },
1318                                        )
1319                                    }
1320                                });
1321                            }
1322                            (WrapperKind::LinkedList, Some(inner_ty)) => {
1323                                tokens.extend(quote! {
1324                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1325                                        key_paths_core::KeyPaths::readable_enum(
1326                                            #name::#v_ident,
1327                                            |e: &#name| match e { #name::#v_ident(v) => v.front(), _ => None }
1328                                        )
1329                                    }
1330                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1331                                        key_paths_core::KeyPaths::writable_enum(
1332                                            #name::#v_ident,
1333                                            |e: &#name| match e { #name::#v_ident(v) => v.front(), _ => None },
1334                                            |e: &mut #name| match e { #name::#v_ident(v) => v.front_mut(), _ => None },
1335                                        )
1336                                    }
1337                                });
1338                            }
1339                            (WrapperKind::BinaryHeap, Some(inner_ty)) => {
1340                                tokens.extend(quote! {
1341                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1342                                        key_paths_core::KeyPaths::readable_enum(
1343                                            #name::#v_ident,
1344                                            |e: &#name| match e { #name::#v_ident(v) => v.peek(), _ => None }
1345                                        )
1346                                    }
1347                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1348                                        key_paths_core::KeyPaths::writable_enum(
1349                                            #name::#v_ident,
1350                                            |e: &#name| match e { #name::#v_ident(v) => v.peek(), _ => None },
1351                                            |e: &mut #name| match e { #name::#v_ident(v) => v.peek_mut().map(|v| &mut **v), _ => None },
1352                                        )
1353                                    }
1354                                });
1355                            }
1356                            (WrapperKind::Result, Some(inner_ty)) => {
1357                                tokens.extend(quote! {
1358                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1359                                        key_paths_core::KeyPaths::readable_enum(
1360                                            #name::#v_ident,
1361                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().ok(), _ => None }
1362                                        )
1363                                    }
1364                                    // Note: Result<T, E> doesn't support writable access for inner type
1365                                    // Only providing readable access
1366                                });
1367                            }
1368                            (WrapperKind::Mutex, Some(inner_ty)) => {
1369                                tokens.extend(quote! {
1370                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1371                                        key_paths_core::KeyPaths::readable_enum(
1372                                            #name::#v_ident,
1373                                            |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None }
1374                                        )
1375                                    }
1376                                    // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
1377                                    // Only providing container-level access
1378                                });
1379                            }
1380                            (WrapperKind::RwLock, Some(inner_ty)) => {
1381                                tokens.extend(quote! {
1382                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1383                                        key_paths_core::KeyPaths::readable_enum(
1384                                            #name::#v_ident,
1385                                            |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None }
1386                                        )
1387                                    }
1388                                    // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
1389                                    // Only providing container-level access
1390                                });
1391                            }
1392                            (WrapperKind::Weak, Some(inner_ty)) => {
1393                                tokens.extend(quote! {
1394                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1395                                        key_paths_core::KeyPaths::readable_enum(
1396                                            #name::#v_ident,
1397                                            |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None }
1398                                        )
1399                                    }
1400                                    // Note: Weak<T> doesn't support writable access (it's immutable)
1401                                    // Note: Weak<T> doesn't support direct access to inner type due to lifetime constraints
1402                                    // Only providing container-level access
1403                                });
1404                            }
1405                            // Nested container combinations for enums - COMMENTED OUT FOR NOW
1406                            /*
1407                            (WrapperKind::OptionBox, Some(inner_ty)) => {
1408                                tokens.extend(quote! {
1409                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1410                                        key_paths_core::KeyPaths::readable_enum(
1411                                            #name::#v_ident,
1412                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().map(|b| &**b), _ => None }
1413                                        )
1414                                    }
1415                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1416                                        key_paths_core::KeyPaths::writable_enum(
1417                                            #name::#v_ident,
1418                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().map(|b| &**b), _ => None },
1419                                            |e: &mut #name| match e { #name::#v_ident(v) => v.as_mut().map(|b| &mut **b), _ => None },
1420                                        )
1421                                    }
1422                                });
1423                            }
1424                            (WrapperKind::OptionRc, Some(inner_ty)) => {
1425                                tokens.extend(quote! {
1426                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1427                                        key_paths_core::KeyPaths::readable_enum(
1428                                            #name::#v_ident,
1429                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().map(|r| &**r), _ => None }
1430                                        )
1431                                    }
1432                                });
1433                            }
1434                            (WrapperKind::OptionArc, Some(inner_ty)) => {
1435                                tokens.extend(quote! {
1436                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1437                                        key_paths_core::KeyPaths::readable_enum(
1438                                            #name::#v_ident,
1439                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().map(|a| &**a), _ => None }
1440                                        )
1441                                    }
1442                                });
1443                            }
1444                            (WrapperKind::BoxOption, Some(inner_ty)) => {
1445                                tokens.extend(quote! {
1446                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1447                                        key_paths_core::KeyPaths::readable_enum(
1448                                            #name::#v_ident,
1449                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None }
1450                                        )
1451                                    }
1452                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1453                                        key_paths_core::KeyPaths::writable_enum(
1454                                            #name::#v_ident,
1455                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None },
1456                                            |e: &mut #name| match e { #name::#v_ident(v) => Some(&mut *v), _ => None },
1457                                        )
1458                                    }
1459                                    pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1460                                        key_paths_core::KeyPaths::readable_enum(
1461                                            #name::#v_ident,
1462                                            |e: &#name| match e { #name::#v_ident(v) => (*v).as_ref(), _ => None }
1463                                        )
1464                                    }
1465                                    pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1466                                        key_paths_core::KeyPaths::writable_enum(
1467                                            #name::#v_ident,
1468                                            |e: &#name| match e { #name::#v_ident(v) => (*v).as_ref(), _ => None },
1469                                            |e: &mut #name| match e { #name::#v_ident(v) => (*v).as_mut(), _ => None },
1470                                        )
1471                                    }
1472                                });
1473                            }
1474                            (WrapperKind::RcOption, Some(inner_ty)) => {
1475                                tokens.extend(quote! {
1476                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1477                                        key_paths_core::KeyPaths::readable_enum(
1478                                            #name::#v_ident,
1479                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None }
1480                                        )
1481                                    }
1482                                    pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1483                                        key_paths_core::KeyPaths::readable_enum(
1484                                            #name::#v_ident,
1485                                            |e: &#name| match e { #name::#v_ident(v) => (*v).as_ref(), _ => None }
1486                                        )
1487                                    }
1488                                });
1489                            }
1490                            (WrapperKind::ArcOption, Some(inner_ty)) => {
1491                                tokens.extend(quote! {
1492                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1493                                        key_paths_core::KeyPaths::readable_enum(
1494                                            #name::#v_ident,
1495                                            |e: &#name| match e { #name::#v_ident(v) => Some(&*v), _ => None }
1496                                        )
1497                                    }
1498                                    pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1499                                        key_paths_core::KeyPaths::readable_enum(
1500                                            #name::#v_ident,
1501                                            |e: &#name| match e { #name::#v_ident(v) => (*v).as_ref(), _ => None }
1502                                        )
1503                                    }
1504                                });
1505                            }
1506                            (WrapperKind::VecOption, Some(inner_ty)) => {
1507                                tokens.extend(quote! {
1508                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1509                                        key_paths_core::KeyPaths::readable_enum(
1510                                            #name::#v_ident,
1511                                            |e: &#name| match e { #name::#v_ident(v) => v.first().and_then(|opt| opt.as_ref()), _ => None }
1512                                        )
1513                                    }
1514                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1515                                        key_paths_core::KeyPaths::writable_enum(
1516                                            #name::#v_ident,
1517                                            |e: &#name| match e { #name::#v_ident(v) => v.first().and_then(|opt| opt.as_ref()), _ => None },
1518                                            |e: &mut #name| match e { #name::#v_ident(v) => v.first_mut().and_then(|opt| opt.as_mut()), _ => None },
1519                                        )
1520                                    }
1521                                });
1522                            }
1523                            (WrapperKind::OptionVec, Some(inner_ty)) => {
1524                                tokens.extend(quote! {
1525                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1526                                        key_paths_core::KeyPaths::readable_enum(
1527                                            #name::#v_ident,
1528                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().and_then(|vec| vec.first()), _ => None }
1529                                        )
1530                                    }
1531                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1532                                        key_paths_core::KeyPaths::writable_enum(
1533                                            #name::#v_ident,
1534                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().and_then(|vec| vec.first()), _ => None },
1535                                            |e: &mut #name| match e { #name::#v_ident(v) => v.as_mut().and_then(|vec| vec.first_mut()), _ => None },
1536                                        )
1537                                    }
1538                                });
1539                            }
1540                            (WrapperKind::HashMapOption, Some(inner_ty)) => {
1541                                tokens.extend(quote! {
1542                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1543                                        key_paths_core::KeyPaths::readable_enum(
1544                                            #name::#v_ident,
1545                                            |e: &#name| match e { #name::#v_ident(v) => v.first().and_then(|(_, opt)| opt.as_ref()), _ => None }
1546                                        )
1547                                    }
1548                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1549                                        key_paths_core::KeyPaths::writable_enum(
1550                                            #name::#v_ident,
1551                                            |e: &#name| match e { #name::#v_ident(v) => v.first().and_then(|(_, opt)| opt.as_ref()), _ => None },
1552                                            |e: &mut #name| match e { #name::#v_ident(v) => v.first_mut().and_then(|(_, opt)| opt.as_mut()), _ => None },
1553                                        )
1554                                    }
1555                                });
1556                            }
1557                            (WrapperKind::OptionHashMap, Some(inner_ty)) => {
1558                                tokens.extend(quote! {
1559                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1560                                        key_paths_core::KeyPaths::readable_enum(
1561                                            #name::#v_ident,
1562                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().and_then(|map| map.first().map(|(_, v)| v)), _ => None }
1563                                        )
1564                                    }
1565                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1566                                        key_paths_core::KeyPaths::writable_enum(
1567                                            #name::#v_ident,
1568                                            |e: &#name| match e { #name::#v_ident(v) => v.as_ref().and_then(|map| map.first().map(|(_, v)| v)), _ => None },
1569                                            |e: &mut #name| match e { #name::#v_ident(v) => v.as_mut().and_then(|map| map.first_mut().map(|(_, v)| v)), _ => None },
1570                                        )
1571                                    }
1572                                });
1573                            }
1574                            */
1575                            (WrapperKind::None, None) => {
1576                                let inner_ty = field_ty;
1577                                tokens.extend(quote! {
1578                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1579                                        key_paths_core::KeyPaths::readable_enum(
1580                                            #name::#v_ident,
1581                                            |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None }
1582                                        )
1583                                    }
1584                                    pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1585                                        key_paths_core::KeyPaths::writable_enum(
1586                                            #name::#v_ident,
1587                                            |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None },
1588                                            |e: &mut #name| match e { #name::#v_ident(v) => Some(v), _ => None },
1589                                        )
1590                                    }
1591                                });
1592                            }
1593                            _ => {
1594                                tokens.extend(quote! {
1595                                    pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #field_ty> {
1596                                        key_paths_core::KeyPaths::readable_enum(
1597                                            #name::#v_ident,
1598                                            |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None }
1599                                        )
1600                                    }
1601                                });
1602                            }
1603                        }
1604                    }
1605                    _ => {
1606                        tokens.extend(quote! {
1607                            compile_error!("Casepaths derive supports only unit and single-field tuple variants");
1608                        });
1609                    }
1610                }
1611            }
1612            tokens
1613        }
1614        _ => quote! {
1615            compile_error!("Keypaths derive supports only structs and enums");
1616        },
1617    };
1618
1619    let expanded = quote! {
1620        impl #name {
1621            #methods
1622        }
1623    };
1624
1625    TokenStream::from(expanded)
1626}
1627
1628fn extract_wrapper_inner_type(ty: &Type) -> (WrapperKind, Option<Type>) {
1629    use syn::{GenericArgument, PathArguments};
1630    
1631    if let Type::Path(tp) = ty {
1632        if let Some(seg) = tp.path.segments.last() {
1633            let ident_str = seg.ident.to_string();
1634            
1635            if let PathArguments::AngleBracketed(ab) = &seg.arguments {
1636                let args: Vec<_> = ab.args.iter().collect();
1637                
1638                // Handle map types (HashMap, BTreeMap) - they have K, V parameters
1639                if ident_str == "HashMap" || ident_str == "BTreeMap" {
1640                    if let (Some(_key_arg), Some(value_arg)) = (args.get(0), args.get(1)) {
1641                        if let GenericArgument::Type(inner) = value_arg {
1642                            eprintln!("Detected {} type, extracting value type", ident_str);
1643                            return match ident_str.as_str() {
1644                                "HashMap" => (WrapperKind::HashMap, Some(inner.clone())),
1645                                "BTreeMap" => (WrapperKind::BTreeMap, Some(inner.clone())),
1646                                _ => (WrapperKind::None, None),
1647                            };
1648                        }
1649                    }
1650                }
1651                // Handle single-parameter container types
1652                else if let Some(arg) = args.get(0) {
1653                    if let GenericArgument::Type(inner) = arg {
1654                        // Check for nested containers first
1655                        let (inner_kind, inner_inner) = extract_wrapper_inner_type(inner);
1656                        
1657                        // Handle nested combinations
1658                        match (ident_str.as_str(), inner_kind) {
1659                            ("Option", WrapperKind::Box) => {
1660                                return (WrapperKind::OptionBox, inner_inner);
1661                            }
1662                            ("Option", WrapperKind::Rc) => {
1663                                return (WrapperKind::OptionRc, inner_inner);
1664                            }
1665                            ("Option", WrapperKind::Arc) => {
1666                                return (WrapperKind::OptionArc, inner_inner);
1667                            }
1668                            ("Option", WrapperKind::Vec) => {
1669                                return (WrapperKind::OptionVec, inner_inner);
1670                            }
1671                            ("Option", WrapperKind::HashMap) => {
1672                                return (WrapperKind::OptionHashMap, inner_inner);
1673                            }
1674                            ("Box", WrapperKind::Option) => {
1675                                return (WrapperKind::BoxOption, inner_inner);
1676                            }
1677                            ("Rc", WrapperKind::Option) => {
1678                                return (WrapperKind::RcOption, inner_inner);
1679                            }
1680                            ("Arc", WrapperKind::Option) => {
1681                                return (WrapperKind::ArcOption, inner_inner);
1682                            }
1683                            ("Vec", WrapperKind::Option) => {
1684                                return (WrapperKind::VecOption, inner_inner);
1685                            }
1686                            ("HashMap", WrapperKind::Option) => {
1687                                return (WrapperKind::HashMapOption, inner_inner);
1688                            }
1689                            ("Arc", WrapperKind::Mutex) => {
1690                                return (WrapperKind::ArcMutex, inner_inner);
1691                            }
1692                            ("Arc", WrapperKind::RwLock) => {
1693                                return (WrapperKind::ArcRwLock, inner_inner);
1694                            }
1695                            _ => {
1696                                // Handle single-level containers
1697                                return match ident_str.as_str() {
1698                                    "Option" => (WrapperKind::Option, Some(inner.clone())),
1699                                    "Box" => (WrapperKind::Box, Some(inner.clone())),
1700                                    "Rc" => (WrapperKind::Rc, Some(inner.clone())),
1701                                    "Arc" => (WrapperKind::Arc, Some(inner.clone())),
1702                                    "Vec" => (WrapperKind::Vec, Some(inner.clone())),
1703                                    "HashSet" => (WrapperKind::HashSet, Some(inner.clone())),
1704                                    "BTreeSet" => (WrapperKind::BTreeSet, Some(inner.clone())),
1705                                    "VecDeque" => (WrapperKind::VecDeque, Some(inner.clone())),
1706                                    "LinkedList" => (WrapperKind::LinkedList, Some(inner.clone())),
1707                                    "BinaryHeap" => (WrapperKind::BinaryHeap, Some(inner.clone())),
1708                                    "Result" => (WrapperKind::Result, Some(inner.clone())),
1709                                    "Mutex" => (WrapperKind::Mutex, Some(inner.clone())),
1710                                    "RwLock" => (WrapperKind::RwLock, Some(inner.clone())),
1711                                    "Weak" => (WrapperKind::Weak, Some(inner.clone())),
1712                                    "Tagged" => (WrapperKind::Tagged, Some(inner.clone())),
1713                                    _ => (WrapperKind::None, None),
1714                                };
1715                            }
1716                        }
1717                    }
1718                }
1719            }
1720        }
1721    }
1722    (WrapperKind::None, None)
1723}
1724
1725
1726fn to_snake_case(name: &str) -> String {
1727    let mut out = String::new();
1728    for (i, c) in name.chars().enumerate() {
1729        if c.is_uppercase() {
1730            if i != 0 {
1731                out.push('_');
1732            }
1733            out.push(c.to_ascii_lowercase());
1734        } else {
1735            out.push(c);
1736        }
1737    }
1738    out
1739}
1740
1741#[proc_macro_derive(WritableKeypaths)]
1742pub fn derive_writable_keypaths(input: TokenStream) -> TokenStream {
1743    let input = parse_macro_input!(input as DeriveInput);
1744    let name = input.ident;
1745
1746    let methods = match input.data {
1747        Data::Struct(data_struct) => match data_struct.fields {
1748            Fields::Named(fields_named) => {
1749                let mut tokens = proc_macro2::TokenStream::new();
1750                for field in fields_named.named.iter() {
1751                    let field_ident = field.ident.as_ref().unwrap();
1752                    let ty = &field.ty;
1753
1754                    let w_fn = format_ident!("{}_w", field_ident);
1755                    let fw_fn = format_ident!("{}_fw", field_ident);
1756                    let fw_at_fn = format_ident!("{}_fw_at", field_ident);
1757
1758                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
1759
1760                    match (kind, inner_ty) {
1761                        (WrapperKind::Option, Some(inner_ty)) => {
1762                            tokens.extend(quote! {
1763                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1764                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1765                                }
1766                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1767                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.as_mut())
1768                                }
1769                            });
1770                        }
1771                        (WrapperKind::Vec, Some(inner_ty)) => {
1772                            tokens.extend(quote! {
1773                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1774                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1775                                }
1776                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1777                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.first_mut())
1778                                }
1779                                pub fn #fw_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1780                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(index))
1781                                }
1782                            });
1783                        }
1784                        (WrapperKind::HashMap, Some(inner_ty)) => {
1785                            tokens.extend(quote! {
1786                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1787                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1788                                }
1789                                pub fn #fw_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1790                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key))
1791                                }
1792                                pub fn #fw_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1793                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key))
1794                                }
1795                            });
1796                        }
1797                        (WrapperKind::Box, Some(inner_ty)) => {
1798                            tokens.extend(quote! {
1799                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1800                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut *s.#field_ident)
1801                                }
1802                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1803                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut *s.#field_ident))
1804                                }
1805                            });
1806                        }
1807                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
1808                            tokens.extend(quote! {
1809                                // Note: Rc/Arc are not writable due to shared ownership
1810                                // Only providing readable methods for these types
1811                            });
1812                        }
1813                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
1814                            tokens.extend(quote! {
1815                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1816                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1817                                }
1818                                pub fn #fw_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1819                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key))
1820                                }
1821                                pub fn #fw_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1822                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(&key))
1823                                }
1824                            });
1825                        }
1826                        (WrapperKind::HashSet, Some(inner_ty)) => {
1827                            tokens.extend(quote! {
1828                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1829                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1830                                }
1831                                // Note: HashSet doesn't have direct mutable access to elements
1832                                // Only providing container-level writable access
1833                            });
1834                        }
1835                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
1836                            tokens.extend(quote! {
1837                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1838                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1839                                }
1840                                // Note: BTreeSet doesn't have direct mutable access to elements
1841                                // Only providing container-level writable access
1842                            });
1843                        }
1844                        (WrapperKind::VecDeque, Some(inner_ty)) => {
1845                            tokens.extend(quote! {
1846                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1847                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1848                                }
1849                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1850                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.front_mut())
1851                                }
1852                                pub fn #fw_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1853                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#field_ident.get_mut(index))
1854                                }
1855                            });
1856                        }
1857                        (WrapperKind::LinkedList, Some(inner_ty)) => {
1858                            tokens.extend(quote! {
1859                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1860                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1861                                }
1862                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1863                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#field_ident.front_mut())
1864                                }
1865                            });
1866                        }
1867                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
1868                            tokens.extend(quote! {
1869                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1870                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1871                                }
1872                                // Note: BinaryHeap peek_mut() returns PeekMut wrapper that doesn't allow direct mutable access
1873                                // Only providing container-level writable access
1874                            });
1875                        }
1876                        (WrapperKind::Result, Some(inner_ty)) => {
1877                            tokens.extend(quote! {
1878                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1879                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1880                                }
1881                                // Note: Result<T, E> doesn't support failable_writable for inner type
1882                                // Only providing container-level writable access
1883                            });
1884                        }
1885                        (WrapperKind::Mutex, Some(inner_ty)) => {
1886                            tokens.extend(quote! {
1887                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1888                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1889                                }
1890                                // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
1891                                // Only providing container-level writable access
1892                            });
1893                        }
1894                        (WrapperKind::RwLock, Some(inner_ty)) => {
1895                            tokens.extend(quote! {
1896                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1897                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1898                                }
1899                                // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
1900                                // Only providing container-level writable access
1901                            });
1902                        }
1903                        (WrapperKind::Weak, Some(inner_ty)) => {
1904                            tokens.extend(quote! {
1905                                // Note: Weak<T> doesn't support writable access (it's immutable)
1906                                // No methods generated for Weak<T>
1907                            });
1908                        }
1909                        (WrapperKind::None, None) => {
1910                            tokens.extend(quote! {
1911                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1912                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1913                                }
1914                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1915                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut s.#field_ident))
1916                                }
1917                            });
1918                        }
1919                        _ => {
1920                            tokens.extend(quote! {
1921                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1922                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#field_ident)
1923                                }
1924                            });
1925                        }
1926                    }
1927                }
1928                tokens
1929            }
1930            Fields::Unnamed(unnamed) => {
1931                let mut tokens = proc_macro2::TokenStream::new();
1932                for (idx, field) in unnamed.unnamed.iter().enumerate() {
1933                    let idx_lit = syn::Index::from(idx);
1934                    let ty = &field.ty;
1935
1936                    let w_fn = format_ident!("f{}_w", idx);
1937                    let fw_fn = format_ident!("f{}_fw", idx);
1938                    let fw_at_fn = format_ident!("f{}_fw_at", idx);
1939
1940                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
1941
1942                    match (kind, inner_ty) {
1943                        (WrapperKind::Option, Some(inner_ty)) => {
1944                            tokens.extend(quote! {
1945                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1946                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1947                                }
1948                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1949                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.as_mut())
1950                                }
1951                            });
1952                        }
1953                        (WrapperKind::Vec, Some(inner_ty)) => {
1954                            tokens.extend(quote! {
1955                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1956                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1957                                }
1958                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1959                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.first_mut())
1960                                }
1961                                pub fn #fw_at_fn(index: &'static usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1962                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.get_mut(*index))
1963                                }
1964                            });
1965                        }
1966                        (WrapperKind::HashMap, Some(inner_ty)) => {
1967                            tokens.extend(quote! {
1968                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1969                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1970                                }
1971                                pub fn #fw_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1972                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key))
1973                                }
1974                                pub fn #fw_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
1975                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key))
1976                                }
1977                            });
1978                        }
1979                        (WrapperKind::Box, Some(inner_ty)) => {
1980                            tokens.extend(quote! {
1981                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1982                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut *s.#idx_lit)
1983                                }
1984                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
1985                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut *s.#idx_lit))
1986                                }
1987                            });
1988                        }
1989                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
1990                            tokens.extend(quote! {
1991                                // Note: Rc/Arc are not writable due to shared ownership
1992                                // Only providing readable methods for these types
1993                            });
1994                        }
1995                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
1996                            tokens.extend(quote! {
1997                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
1998                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
1999                                }
2000                                pub fn #fw_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2001                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key))
2002                                }
2003                                pub fn #fw_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2004                                    key_paths_core::KeyPaths::failable_writable(move |s: &mut #name| s.#idx_lit.get_mut(&key))
2005                                }
2006                            });
2007                        }
2008                        (WrapperKind::HashSet, Some(inner_ty)) => {
2009                            tokens.extend(quote! {
2010                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2011                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2012                                }
2013                                // Note: HashSet doesn't have direct mutable access to elements
2014                                // Only providing container-level writable access
2015                            });
2016                        }
2017                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
2018                            tokens.extend(quote! {
2019                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2020                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2021                                }
2022                                // Note: BTreeSet doesn't have direct mutable access to elements
2023                                // Only providing container-level writable access
2024                            });
2025                        }
2026                        (WrapperKind::VecDeque, Some(inner_ty)) => {
2027                            tokens.extend(quote! {
2028                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2029                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2030                                }
2031                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2032                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.front_mut())
2033                                }
2034                            });
2035                        }
2036                        (WrapperKind::LinkedList, Some(inner_ty)) => {
2037                            tokens.extend(quote! {
2038                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2039                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2040                                }
2041                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2042                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| s.#idx_lit.front_mut())
2043                                }
2044                            });
2045                        }
2046                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
2047                            tokens.extend(quote! {
2048                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2049                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2050                                }
2051                                // Note: BinaryHeap peek_mut() returns PeekMut wrapper that doesn't allow direct mutable access
2052                                // Only providing container-level writable access
2053                            });
2054                        }
2055                        (WrapperKind::Result, Some(inner_ty)) => {
2056                            tokens.extend(quote! {
2057                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2058                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2059                                }
2060                                // Note: Result<T, E> doesn't support failable_writable for inner type
2061                                // Only providing container-level writable access
2062                            });
2063                        }
2064                        (WrapperKind::Mutex, Some(inner_ty)) => {
2065                            tokens.extend(quote! {
2066                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2067                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2068                                }
2069                                // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
2070                                // Only providing container-level writable access
2071                            });
2072                        }
2073                        (WrapperKind::RwLock, Some(inner_ty)) => {
2074                            tokens.extend(quote! {
2075                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2076                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2077                                }
2078                                // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
2079                                // Only providing container-level writable access
2080                            });
2081                        }
2082                        (WrapperKind::Weak, Some(inner_ty)) => {
2083                            tokens.extend(quote! {
2084                                // Note: Weak<T> doesn't support writable access (it's immutable)
2085                                // No methods generated for Weak<T>
2086                            });
2087                        }
2088                        (WrapperKind::None, None) => {
2089                            tokens.extend(quote! {
2090                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2091                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2092                                }
2093                                pub fn #fw_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2094                                    key_paths_core::KeyPaths::failable_writable(|s: &mut #name| Some(&mut s.#idx_lit))
2095                                }
2096                            });
2097                        }
2098                        _ => {
2099                            tokens.extend(quote! {
2100                                pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2101                                    key_paths_core::KeyPaths::writable(|s: &mut #name| &mut s.#idx_lit)
2102                                }
2103                            });
2104                        }
2105                    }
2106                }
2107                tokens
2108            }
2109            _ => quote! {
2110                compile_error!("WritableKeypaths derive supports only structs with named or unnamed fields");
2111            },
2112        },
2113        _ => quote! {
2114            compile_error!("WritableKeypaths derive supports only structs");
2115        },
2116    };
2117
2118    let expanded = quote! {
2119        impl #name {
2120            #methods
2121        }
2122    };
2123
2124    TokenStream::from(expanded)
2125}
2126
2127#[proc_macro_derive(Keypath)]
2128pub fn derive_keypath(input: TokenStream) -> TokenStream {
2129    let input = parse_macro_input!(input as DeriveInput);
2130    let name = input.ident;
2131
2132    let methods = match input.data {
2133        Data::Struct(data_struct) => match data_struct.fields {
2134            Fields::Named(fields_named) => {
2135                let mut tokens = proc_macro2::TokenStream::new();
2136                for field in fields_named.named.iter() {
2137                    let field_ident = field.ident.as_ref().unwrap();
2138                    let ty = &field.ty;
2139
2140                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
2141
2142                    match (kind, inner_ty) {
2143                        (WrapperKind::Option, Some(inner_ty)) => {
2144                            // For Option<T>, return failable readable keypath to inner type
2145                            tokens.extend(quote! {
2146                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2147                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref())
2148                                }
2149                            });
2150                        }
2151                        (WrapperKind::Vec, Some(inner_ty)) => {
2152                            // For Vec<T>, return failable readable keypath to first element
2153                            tokens.extend(quote! {
2154                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2155                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.first())
2156                                }
2157                            });
2158                        }
2159                        (WrapperKind::HashMap, Some(inner_ty)) => {
2160                            // For HashMap<K,V>, return readable keypath to the container
2161                            tokens.extend(quote! {
2162                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2163                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2164                                }
2165                            });
2166                        }
2167                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
2168                            // For BTreeMap<K,V>, return readable keypath to the container
2169                            tokens.extend(quote! {
2170                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2171                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2172                                }
2173                            });
2174                        }
2175                        (WrapperKind::Box, Some(inner_ty)) => {
2176                            // For Box<T>, return readable keypath to inner type
2177                            tokens.extend(quote! {
2178                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2179                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
2180                                }
2181                            });
2182                        }
2183                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
2184                            // For Rc<T>/Arc<T>, return readable keypath to inner type
2185                            tokens.extend(quote! {
2186                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2187                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
2188                                }
2189                            });
2190                        }
2191                        (WrapperKind::HashSet, Some(inner_ty)) => {
2192                            // For HashSet<T>, return failable readable keypath to any element
2193                            tokens.extend(quote! {
2194                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2195                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.iter().next())
2196                                }
2197                            });
2198                        }
2199                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
2200                            // For BTreeSet<T>, return failable readable keypath to any element
2201                            tokens.extend(quote! {
2202                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2203                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.iter().next())
2204                                }
2205                            });
2206                        }
2207                        (WrapperKind::VecDeque, Some(inner_ty)) => {
2208                            // For VecDeque<T>, return failable readable keypath to front element
2209                            tokens.extend(quote! {
2210                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2211                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.front())
2212                                }
2213                            });
2214                        }
2215                        (WrapperKind::LinkedList, Some(inner_ty)) => {
2216                            // For LinkedList<T>, return failable readable keypath to front element
2217                            tokens.extend(quote! {
2218                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2219                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.front())
2220                                }
2221                            });
2222                        }
2223                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
2224                            // For BinaryHeap<T>, return failable readable keypath to peek element
2225                            tokens.extend(quote! {
2226                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2227                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.peek())
2228                                }
2229                            });
2230                        }
2231                        (WrapperKind::Result, Some(inner_ty)) => {
2232                            // For Result<T, E>, return failable readable keypath to Ok value
2233                            tokens.extend(quote! {
2234                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2235                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().ok())
2236                                }
2237                            });
2238                        }
2239                        (WrapperKind::Mutex, Some(inner_ty)) => {
2240                            // For Mutex<T>, return readable keypath to the container (not inner type due to lifetime issues)
2241                            tokens.extend(quote! {
2242                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2243                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2244                                }
2245                            });
2246                        }
2247                        (WrapperKind::RwLock, Some(inner_ty)) => {
2248                            // For RwLock<T>, return readable keypath to the container (not inner type due to lifetime issues)
2249                            tokens.extend(quote! {
2250                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2251                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2252                                }
2253                            });
2254                        }
2255                        (WrapperKind::Weak, Some(inner_ty)) => {
2256                            // For Weak<T>, return readable keypath to the container (not inner type due to lifetime issues)
2257                            tokens.extend(quote! {
2258                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2259                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2260                                }
2261                            });
2262                        }
2263                        (WrapperKind::None, None) => {
2264                            // For basic types, return readable keypath
2265                            tokens.extend(quote! {
2266                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2267                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2268                                }
2269                            });
2270                        }
2271                        _ => {
2272                            // For unknown types, return readable keypath
2273                            tokens.extend(quote! {
2274                                pub fn #field_ident() -> key_paths_core::KeyPaths<#name, #ty> {
2275                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2276                                }
2277                            });
2278                        }
2279                    }
2280                }
2281                tokens
2282            }
2283            Fields::Unnamed(unnamed) => {
2284                let mut tokens = proc_macro2::TokenStream::new();
2285                for (idx, field) in unnamed.unnamed.iter().enumerate() {
2286                    let idx_lit = syn::Index::from(idx);
2287                    let ty = &field.ty;
2288                    let field_name = format_ident!("f{}", idx);
2289
2290                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
2291
2292                    match (kind, inner_ty) {
2293                        (WrapperKind::Option, Some(inner_ty)) => {
2294                            tokens.extend(quote! {
2295                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2296                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref())
2297                                }
2298                            });
2299                        }
2300                        (WrapperKind::Vec, Some(inner_ty)) => {
2301                            tokens.extend(quote! {
2302                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2303                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.first())
2304                                }
2305                            });
2306                        }
2307                        (WrapperKind::HashMap, Some(inner_ty)) => {
2308                            tokens.extend(quote! {
2309                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2310                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2311                                }
2312                            });
2313                        }
2314                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
2315                            tokens.extend(quote! {
2316                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2317                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2318                                }
2319                            });
2320                        }
2321                        (WrapperKind::Box, Some(inner_ty)) => {
2322                            tokens.extend(quote! {
2323                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2324                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
2325                                }
2326                            });
2327                        }
2328                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
2329                            tokens.extend(quote! {
2330                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2331                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
2332                                }
2333                            });
2334                        }
2335                        (WrapperKind::HashSet, Some(inner_ty)) => {
2336                            tokens.extend(quote! {
2337                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2338                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.iter().next())
2339                                }
2340                            });
2341                        }
2342                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
2343                            tokens.extend(quote! {
2344                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2345                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.iter().next())
2346                                }
2347                            });
2348                        }
2349                        (WrapperKind::VecDeque, Some(inner_ty)) => {
2350                            tokens.extend(quote! {
2351                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2352                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.front())
2353                                }
2354                            });
2355                        }
2356                        (WrapperKind::LinkedList, Some(inner_ty)) => {
2357                            tokens.extend(quote! {
2358                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2359                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.front())
2360                                }
2361                            });
2362                        }
2363                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
2364                            tokens.extend(quote! {
2365                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2366                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.peek())
2367                                }
2368                            });
2369                        }
2370                        (WrapperKind::Result, Some(inner_ty)) => {
2371                            tokens.extend(quote! {
2372                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2373                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().ok())
2374                                }
2375                            });
2376                        }
2377                        (WrapperKind::Mutex, Some(inner_ty)) => {
2378                            tokens.extend(quote! {
2379                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2380                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2381                                }
2382                            });
2383                        }
2384                        (WrapperKind::RwLock, Some(inner_ty)) => {
2385                            tokens.extend(quote! {
2386                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2387                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2388                                }
2389                            });
2390                        }
2391                        (WrapperKind::Weak, Some(inner_ty)) => {
2392                            tokens.extend(quote! {
2393                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2394                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2395                                }
2396                            });
2397                        }
2398                        (WrapperKind::None, None) => {
2399                            tokens.extend(quote! {
2400                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2401                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2402                                }
2403                            });
2404                        }
2405                        _ => {
2406                            tokens.extend(quote! {
2407                                pub fn #field_name() -> key_paths_core::KeyPaths<#name, #ty> {
2408                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2409                                }
2410                            });
2411                        }
2412                    }
2413                }
2414                tokens
2415            }
2416            _ => quote! {
2417                compile_error!("Keypath derive supports only structs with named or unnamed fields");
2418            },
2419        },
2420        Data::Enum(data_enum) => {
2421            let mut tokens = proc_macro2::TokenStream::new();
2422            for variant in data_enum.variants.iter() {
2423                let v_ident = &variant.ident;
2424                let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
2425
2426                match &variant.fields {
2427                    Fields::Unit => {
2428                        // Unit variant - return readable keypath to the variant itself
2429                        tokens.extend(quote! {
2430                            pub fn #snake() -> key_paths_core::KeyPaths<#name, #name> {
2431                                key_paths_core::KeyPaths::readable(|s: &#name| s)
2432                            }
2433                        });
2434                    }
2435                    Fields::Unnamed(unnamed) => {
2436                        if unnamed.unnamed.len() == 1 {
2437                            // Single-field tuple variant - smart keypath selection
2438                            let field_ty = &unnamed.unnamed[0].ty;
2439                            let (kind, inner_ty) = extract_wrapper_inner_type(field_ty);
2440
2441                            match (kind, inner_ty) {
2442                                (WrapperKind::Option, Some(inner_ty)) => {
2443                                    tokens.extend(quote! {
2444                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2445                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2446                                                #name::#v_ident(inner) => inner.as_ref(),
2447                                                _ => None,
2448                                            })
2449                                        }
2450                                    });
2451                                }
2452                                (WrapperKind::Vec, Some(inner_ty)) => {
2453                                    tokens.extend(quote! {
2454                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2455                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2456                                                #name::#v_ident(inner) => inner.first(),
2457                                                _ => None,
2458                                            })
2459                                        }
2460                                    });
2461                                }
2462                                (WrapperKind::HashMap, Some(_inner_ty)) => {
2463                                    tokens.extend(quote! {
2464                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2465                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2466                                                #name::#v_ident(inner) => Some(inner),
2467                                                _ => None,
2468                                            })
2469                                        }
2470                                    });
2471                                }
2472                                (WrapperKind::BTreeMap, Some(_inner_ty)) => {
2473                                    tokens.extend(quote! {
2474                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2475                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2476                                                #name::#v_ident(inner) => Some(inner),
2477                                                _ => None,
2478                                            })
2479                                        }
2480                                    });
2481                                }
2482                                (WrapperKind::Box, Some(inner_ty)) => {
2483                                    tokens.extend(quote! {
2484                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2485                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2486                                                #name::#v_ident(inner) => Some(&**inner),
2487                                                _ => None,
2488                                            })
2489                                        }
2490                                    });
2491                                }
2492                                (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
2493                                    tokens.extend(quote! {
2494                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2495                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2496                                                #name::#v_ident(inner) => Some(&**inner),
2497                                                _ => None,
2498                                            })
2499                                        }
2500                                    });
2501                                }
2502                                (WrapperKind::HashSet, Some(inner_ty)) => {
2503                                    tokens.extend(quote! {
2504                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2505                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2506                                                #name::#v_ident(inner) => inner.iter().next(),
2507                                                _ => None,
2508                                            })
2509                                        }
2510                                    });
2511                                }
2512                                (WrapperKind::BTreeSet, Some(inner_ty)) => {
2513                                    tokens.extend(quote! {
2514                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2515                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2516                                                #name::#v_ident(inner) => inner.iter().next(),
2517                                                _ => None,
2518                                            })
2519                                        }
2520                                    });
2521                                }
2522                                (WrapperKind::VecDeque, Some(inner_ty)) => {
2523                                    tokens.extend(quote! {
2524                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2525                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2526                                                #name::#v_ident(inner) => inner.front(),
2527                                                _ => None,
2528                                            })
2529                                        }
2530                                    });
2531                                }
2532                                (WrapperKind::LinkedList, Some(inner_ty)) => {
2533                                    tokens.extend(quote! {
2534                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2535                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2536                                                #name::#v_ident(inner) => inner.front(),
2537                                                _ => None,
2538                                            })
2539                                        }
2540                                    });
2541                                }
2542                                (WrapperKind::BinaryHeap, Some(inner_ty)) => {
2543                                    tokens.extend(quote! {
2544                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2545                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2546                                                #name::#v_ident(inner) => inner.peek(),
2547                                                _ => None,
2548                                            })
2549                                        }
2550                                    });
2551                                }
2552                                (WrapperKind::Result, Some(inner_ty)) => {
2553                                    tokens.extend(quote! {
2554                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2555                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2556                                                #name::#v_ident(inner) => inner.as_ref().ok(),
2557                                                _ => None,
2558                                            })
2559                                        }
2560                                    });
2561                                }
2562                                (WrapperKind::Mutex, Some(inner_ty)) => {
2563                                    tokens.extend(quote! {
2564                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2565                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2566                                                #name::#v_ident(inner) => Some(inner),
2567                                                _ => None,
2568                                            })
2569                                        }
2570                                    });
2571                                }
2572                                (WrapperKind::RwLock, Some(inner_ty)) => {
2573                                    tokens.extend(quote! {
2574                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2575                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2576                                                #name::#v_ident(inner) => Some(inner),
2577                                                _ => None,
2578                                            })
2579                                        }
2580                                    });
2581                                }
2582                                (WrapperKind::Weak, Some(inner_ty)) => {
2583                                    tokens.extend(quote! {
2584                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2585                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2586                                                #name::#v_ident(inner) => Some(inner),
2587                                                _ => None,
2588                                            })
2589                                        }
2590                                    });
2591                                }
2592                                (WrapperKind::None, None) => {
2593                                    // Basic type - return failable readable keypath
2594                                    tokens.extend(quote! {
2595                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2596                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2597                                                #name::#v_ident(inner) => Some(inner),
2598                                                _ => None,
2599                                            })
2600                                        }
2601                                    });
2602                                }
2603                                _ => {
2604                                    // Unknown type - return failable readable keypath
2605                                    tokens.extend(quote! {
2606                                        pub fn #snake() -> key_paths_core::KeyPaths<#name, #field_ty> {
2607                                            key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2608                                                #name::#v_ident(inner) => Some(inner),
2609                                                _ => None,
2610                                            })
2611                                        }
2612                                    });
2613                                }
2614                            }
2615                        } else {
2616                            // Multi-field tuple variant - return failable readable keypath to the variant
2617                            tokens.extend(quote! {
2618                                pub fn #snake() -> key_paths_core::KeyPaths<#name, #name> {
2619                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2620                                        #name::#v_ident(..) => Some(s),
2621                                        _ => None,
2622                                    })
2623                                }
2624                            });
2625                        }
2626                    }
2627                    Fields::Named(named) => {
2628                        // Named field variant - return failable readable keypath to the variant
2629                        tokens.extend(quote! {
2630                            pub fn #snake() -> key_paths_core::KeyPaths<#name, #name> {
2631                                key_paths_core::KeyPaths::failable_readable(|s: &#name| match s {
2632                                    #name::#v_ident { .. } => Some(s),
2633                                    _ => None,
2634                                })
2635                            }
2636                        });
2637                    }
2638                }
2639            }
2640            tokens
2641        }
2642        _ => quote! {
2643            compile_error!("Keypath derive supports only structs and enums");
2644        },
2645    };
2646
2647    let expanded = quote! {
2648        impl #name {
2649            #methods
2650        }
2651    };
2652
2653    TokenStream::from(expanded)
2654}
2655
2656#[proc_macro_derive(ReadableKeypaths)]
2657pub fn derive_readable_keypaths(input: TokenStream) -> TokenStream {
2658    let input = parse_macro_input!(input as DeriveInput);
2659    let name = input.ident;
2660
2661    let methods = match input.data {
2662        Data::Struct(data_struct) => match data_struct.fields {
2663            Fields::Named(fields_named) => {
2664                let mut tokens = proc_macro2::TokenStream::new();
2665                for field in fields_named.named.iter() {
2666                    let field_ident = field.ident.as_ref().unwrap();
2667                    let ty = &field.ty;
2668
2669                    let r_fn = format_ident!("{}_r", field_ident);
2670                    let fr_fn = format_ident!("{}_fr", field_ident);
2671                    let fr_at_fn = format_ident!("{}_fr_at", field_ident);
2672
2673                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
2674
2675                    match (kind, inner_ty) {
2676                        (WrapperKind::Option, Some(inner_ty)) => {
2677                            tokens.extend(quote! {
2678                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2679                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2680                                }
2681                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2682                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref())
2683                                }
2684                            });
2685                        }
2686                        (WrapperKind::Vec, Some(inner_ty)) => {
2687                            tokens.extend(quote! {
2688                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2689                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2690                                }
2691                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2692                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.first())
2693                                }
2694                                pub fn #fr_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2695                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(index))
2696                                }
2697                            });
2698                        }
2699                        (WrapperKind::HashMap, Some(inner_ty)) => {
2700                            tokens.extend(quote! {
2701                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2702                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2703                                }
2704                                pub fn #fr_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2705                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key))
2706                                }
2707                                pub fn #fr_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2708                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key))
2709                                }
2710                            });
2711                        }
2712                        (WrapperKind::Box, Some(inner_ty)) => {
2713                            tokens.extend(quote! {
2714                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2715                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
2716                                }
2717                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2718                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#field_ident))
2719                                }
2720                            });
2721                        }
2722                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
2723                            tokens.extend(quote! {
2724                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2725                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#field_ident)
2726                                }
2727                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2728                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#field_ident))
2729                                }
2730                            });
2731                        }
2732                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
2733                            tokens.extend(quote! {
2734                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2735                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2736                                }
2737                                pub fn #fr_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2738                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key))
2739                                }
2740                                pub fn #fr_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2741                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(&key))
2742                                }
2743                            });
2744                        }
2745                        (WrapperKind::HashSet, Some(inner_ty)) => {
2746                            tokens.extend(quote! {
2747                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2748                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2749                                }
2750                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2751                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.iter().next())
2752                                }
2753                            });
2754                        }
2755                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
2756                            tokens.extend(quote! {
2757                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2758                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2759                                }
2760                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2761                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.iter().next())
2762                                }
2763                            });
2764                        }
2765                        (WrapperKind::VecDeque, Some(inner_ty)) => {
2766                            tokens.extend(quote! {
2767                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2768                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2769                                }
2770                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2771                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.front())
2772                                }
2773                                pub fn #fr_at_fn(index: usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2774                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#field_ident.get(index))
2775                                }
2776                            });
2777                        }
2778                        (WrapperKind::LinkedList, Some(inner_ty)) => {
2779                            tokens.extend(quote! {
2780                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2781                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2782                                }
2783                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2784                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.front())
2785                                }
2786                            });
2787                        }
2788                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
2789                            tokens.extend(quote! {
2790                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2791                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2792                                }
2793                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2794                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.peek())
2795                                }
2796                            });
2797                        }
2798                        (WrapperKind::Result, Some(inner_ty)) => {
2799                            tokens.extend(quote! {
2800                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2801                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2802                                }
2803                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2804                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#field_ident.as_ref().ok())
2805                                }
2806                            });
2807                        }
2808                        (WrapperKind::Mutex, Some(inner_ty)) => {
2809                            tokens.extend(quote! {
2810                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2811                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2812                                }
2813                                // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
2814                                // Only providing container-level access
2815                            });
2816                        }
2817                        (WrapperKind::RwLock, Some(inner_ty)) => {
2818                            tokens.extend(quote! {
2819                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2820                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2821                                }
2822                                // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
2823                                // Only providing container-level access
2824                            });
2825                        }
2826                        (WrapperKind::Weak, Some(inner_ty)) => {
2827                            tokens.extend(quote! {
2828                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2829                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2830                                }
2831                                // Note: Weak<T> doesn't support direct access to inner type due to lifetime constraints
2832                                // Only providing container-level access
2833                            });
2834                        }
2835                        (WrapperKind::None, None) => {
2836                            tokens.extend(quote! {
2837                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2838                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2839                                }
2840                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2841                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&s.#field_ident))
2842                                }
2843                            });
2844                        }
2845                        _ => {
2846                            tokens.extend(quote! {
2847                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2848                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#field_ident)
2849                                }
2850                            });
2851                        }
2852                    }
2853                }
2854                tokens
2855            }
2856            Fields::Unnamed(unnamed) => {
2857                let mut tokens = proc_macro2::TokenStream::new();
2858                for (idx, field) in unnamed.unnamed.iter().enumerate() {
2859                    let idx_lit = syn::Index::from(idx);
2860                    let ty = &field.ty;
2861
2862                    let r_fn = format_ident!("f{}_r", idx);
2863                    let fr_fn = format_ident!("f{}_fr", idx);
2864                    let fr_at_fn = format_ident!("f{}_fr_at", idx);
2865
2866                    let (kind, inner_ty) = extract_wrapper_inner_type(ty);
2867
2868                    match (kind, inner_ty) {
2869                        (WrapperKind::Option, Some(inner_ty)) => {
2870                            tokens.extend(quote! {
2871                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2872                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2873                                }
2874                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2875                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref())
2876                                }
2877                            });
2878                        }
2879                        (WrapperKind::Vec, Some(inner_ty)) => {
2880                            tokens.extend(quote! {
2881                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2882                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2883                                }
2884                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2885                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.first())
2886                                }
2887                                pub fn #fr_at_fn(index: &'static usize) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2888                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.get(*index))
2889                                }
2890                            });
2891                        }
2892                        (WrapperKind::HashMap, Some(inner_ty)) => {
2893                            tokens.extend(quote! {
2894                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2895                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2896                                }
2897                                pub fn #fr_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2898                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key))
2899                                }
2900                                pub fn #fr_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2901                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key))
2902                                }
2903                            });
2904                        }
2905                        (WrapperKind::Box, Some(inner_ty)) => {
2906                            tokens.extend(quote! {
2907                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2908                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
2909                                }
2910                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2911                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#idx_lit))
2912                                }
2913                            });
2914                        }
2915                        (WrapperKind::Rc, Some(inner_ty)) | (WrapperKind::Arc, Some(inner_ty)) => {
2916                            tokens.extend(quote! {
2917                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2918                                    key_paths_core::KeyPaths::readable(|s: &#name| &*s.#idx_lit)
2919                                }
2920                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2921                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&*s.#idx_lit))
2922                                }
2923                            });
2924                        }
2925                        (WrapperKind::BTreeMap, Some(inner_ty)) => {
2926                            tokens.extend(quote! {
2927                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2928                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2929                                }
2930                                pub fn #fr_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2931                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key))
2932                                }
2933                                pub fn #fr_at_fn(key: String) -> key_paths_core::KeyPaths<#name, #inner_ty> {
2934                                    key_paths_core::KeyPaths::failable_readable(move |s: &#name| s.#idx_lit.get(&key))
2935                                }
2936                            });
2937                        }
2938                        (WrapperKind::HashSet, Some(inner_ty)) => {
2939                            tokens.extend(quote! {
2940                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2941                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2942                                }
2943                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2944                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.iter().next())
2945                                }
2946                            });
2947                        }
2948                        (WrapperKind::BTreeSet, Some(inner_ty)) => {
2949                            tokens.extend(quote! {
2950                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2951                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2952                                }
2953                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2954                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.iter().next())
2955                                }
2956                            });
2957                        }
2958                        (WrapperKind::VecDeque, Some(inner_ty)) => {
2959                            tokens.extend(quote! {
2960                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2961                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2962                                }
2963                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2964                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.front())
2965                                }
2966                            });
2967                        }
2968                        (WrapperKind::LinkedList, Some(inner_ty)) => {
2969                            tokens.extend(quote! {
2970                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2971                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2972                                }
2973                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2974                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.front())
2975                                }
2976                            });
2977                        }
2978                        (WrapperKind::BinaryHeap, Some(inner_ty)) => {
2979                            tokens.extend(quote! {
2980                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2981                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2982                                }
2983                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2984                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.peek())
2985                                }
2986                            });
2987                        }
2988                        (WrapperKind::Result, Some(inner_ty)) => {
2989                            tokens.extend(quote! {
2990                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
2991                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
2992                                }
2993                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
2994                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| s.#idx_lit.as_ref().ok())
2995                                }
2996                            });
2997                        }
2998                        (WrapperKind::Mutex, Some(inner_ty)) => {
2999                            tokens.extend(quote! {
3000                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
3001                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
3002                                }
3003                                // Note: Mutex<T> doesn't support direct access to inner type due to lifetime constraints
3004                                // Only providing container-level access
3005                            });
3006                        }
3007                        (WrapperKind::RwLock, Some(inner_ty)) => {
3008                            tokens.extend(quote! {
3009                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
3010                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
3011                                }
3012                                // Note: RwLock<T> doesn't support direct access to inner type due to lifetime constraints
3013                                // Only providing container-level access
3014                            });
3015                        }
3016                        (WrapperKind::Weak, Some(inner_ty)) => {
3017                            tokens.extend(quote! {
3018                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
3019                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
3020                                }
3021                                // Note: Weak<T> doesn't support direct access to inner type due to lifetime constraints
3022                                // Only providing container-level access
3023                            });
3024                        }
3025                        (WrapperKind::None, None) => {
3026                            tokens.extend(quote! {
3027                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
3028                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
3029                                }
3030                                pub fn #fr_fn() -> key_paths_core::KeyPaths<#name, #ty> {
3031                                    key_paths_core::KeyPaths::failable_readable(|s: &#name| Some(&s.#idx_lit))
3032                                }
3033                            });
3034                        }
3035                        _ => {
3036                            tokens.extend(quote! {
3037                                pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #ty> {
3038                                    key_paths_core::KeyPaths::readable(|s: &#name| &s.#idx_lit)
3039                                }
3040                            });
3041                        }
3042                    }
3043                }
3044                tokens
3045            }
3046            _ => quote! {
3047                compile_error!("ReadableKeypaths derive supports only structs with named or unnamed fields");
3048            },
3049        },
3050        _ => quote! {
3051            compile_error!("ReadableKeypaths derive supports only structs");
3052        },
3053    };
3054
3055    let expanded = quote! {
3056        impl #name {
3057            #methods
3058        }
3059    };
3060
3061    TokenStream::from(expanded)
3062}
3063
3064#[proc_macro_derive(Casepaths)]
3065pub fn derive_casepaths(input: TokenStream) -> TokenStream {
3066    let input = parse_macro_input!(input as DeriveInput);
3067    let name = input.ident;
3068
3069    let tokens = match input.data {
3070        Data::Enum(data_enum) => {
3071            let mut tokens = proc_macro2::TokenStream::new();
3072            for variant in data_enum.variants.iter() {
3073                let v_ident = &variant.ident;
3074                let snake = format_ident!("{}", to_snake_case(&v_ident.to_string()));
3075                let r_fn = format_ident!("{}_case_r", snake);
3076                let w_fn = format_ident!("{}_case_w", snake);
3077
3078                match &variant.fields {
3079                    Fields::Unit => {
3080                        tokens.extend(quote! {
3081                            pub fn #r_fn() -> key_paths_core::KeyPaths<#name, ()> {
3082                                static UNIT: () = ();
3083                                key_paths_core::KeyPaths::readable_enum(
3084                                    |_| #name::#v_ident,
3085                                    |e: &#name| match e { #name::#v_ident => Some(&UNIT), _ => None }
3086                                )
3087                            }
3088                        });
3089                    }
3090                    Fields::Unnamed(unnamed) if unnamed.unnamed.len() == 1 => {
3091                        let inner_ty = &unnamed.unnamed.first().unwrap().ty;
3092                        tokens.extend(quote! {
3093                            pub fn #r_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
3094                                key_paths_core::KeyPaths::readable_enum(
3095                                    #name::#v_ident,
3096                                    |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None }
3097                                )
3098                            }
3099                            pub fn #w_fn() -> key_paths_core::KeyPaths<#name, #inner_ty> {
3100                                key_paths_core::KeyPaths::writable_enum(
3101                                    #name::#v_ident,
3102                                    |e: &#name| match e { #name::#v_ident(v) => Some(v), _ => None },
3103                                    |e: &mut #name| match e { #name::#v_ident(v) => Some(v), _ => None },
3104                                )
3105                            }
3106                        });
3107                    }
3108                    _ => {
3109                        tokens.extend(quote! {
3110                            compile_error!("Casepaths derive supports only unit and single-field tuple variants");
3111                        });
3112                    }
3113                }
3114            }
3115            tokens
3116        }
3117        _ => quote! { compile_error!("Casepaths can only be derived for enums"); },
3118    };
3119
3120    let expanded = quote! {
3121        impl #name {
3122            #tokens
3123        }
3124    };
3125
3126    TokenStream::from(expanded)
3127}
3128
3129/// A helper macro that provides suggestions when there are type mismatches with container types.
3130/// This macro helps users understand when to use adapter methods like for_arc(), for_box(), etc.
3131#[proc_macro]
3132pub fn keypath_suggestion(input: TokenStream) -> TokenStream {
3133    let input_str = input.to_string();
3134    
3135    // Parse the input to understand what the user is trying to do
3136    let suggestion = if input_str.contains("Arc<") && input_str.contains("KeyPaths<") {
3137        "💡 Suggestion: If you have a KeyPaths<SomeStruct, Value> but need KeyPaths<Arc<SomeStruct>, Value>, use the .for_arc() adapter method:\n   let arc_keypath = your_keypath.for_arc();"
3138    } else if input_str.contains("Box<") && input_str.contains("KeyPaths<") {
3139        "💡 Suggestion: If you have a KeyPaths<SomeStruct, Value> but need KeyPaths<Box<SomeStruct>, Value>, use the .for_box() adapter method:\n   let box_keypath = your_keypath.for_box();"
3140    } else if input_str.contains("Rc<") && input_str.contains("KeyPaths<") {
3141        "💡 Suggestion: If you have a KeyPaths<SomeStruct, Value> but need KeyPaths<Rc<SomeStruct>, Value>, use the .for_rc() adapter method:\n   let rc_keypath = your_keypath.for_rc();"
3142    } else if input_str.contains("Option<") && input_str.contains("KeyPaths<") {
3143        "💡 Suggestion: If you have a KeyPaths<SomeStruct, Value> but need KeyPaths<Option<SomeStruct>, Value>, use the .for_option() adapter method:\n   let option_keypath = your_keypath.for_option();"
3144    } else if input_str.contains("Result<") && input_str.contains("KeyPaths<") {
3145        "💡 Suggestion: If you have a KeyPaths<SomeStruct, Value> but need KeyPaths<Result<SomeStruct, E>, Value>, use the .for_result() adapter method:\n   let result_keypath = your_keypath.for_result();"
3146    } else if input_str.contains("Mutex<") && input_str.contains("KeyPaths<") {
3147        "💡 Suggestion: For Mutex<T> containers, use the .with_mutex() method from WithContainer trait (no cloning):\n   use key_paths_core::WithContainer;\n   your_keypath.with_mutex(&mutex, |value| { /* work with value */ });"
3148    } else if input_str.contains("RwLock<") && input_str.contains("KeyPaths<") {
3149        "💡 Suggestion: For RwLock<T> containers, use the .with_rwlock() method from WithContainer trait (no cloning):\n   use key_paths_core::WithContainer;\n   your_keypath.with_rwlock(&rwlock, |value| { /* work with value */ });"
3150    } else {
3151        "💡 Suggestion: Use adapter methods to work with different container types:\n   - .for_arc() for Arc<T>\n   - .for_box() for Box<T>\n   - .for_rc() for Rc<T>\n   - .for_option() for Option<T>\n   - .for_result() for Result<T, E>\n   - .with_mutex() for Mutex<T> (import WithContainer trait)\n   - .with_rwlock() for RwLock<T> (import WithContainer trait)\n   - .for_arc_mutex() for Arc<Mutex<T>> (with parking_lot feature)\n   - .for_arc_rwlock() for Arc<RwLock<T>> (with parking_lot feature)"
3152    };
3153    
3154    let expanded = quote! {
3155        compile_error!(#suggestion);
3156    };
3157    
3158    TokenStream::from(expanded)
3159}
3160
3161/// A helper macro that provides compile-time suggestions for common KeyPaths usage patterns.
3162/// This macro can be used to get helpful error messages when there are type mismatches.
3163#[proc_macro]
3164pub fn keypath_help(input: TokenStream) -> TokenStream {
3165    let input_str = input.to_string();
3166    
3167    let help_message = if input_str.is_empty() {
3168        "🔧 KeyPaths Help: Use adapter methods to work with different container types:\n   - .for_arc() for Arc<T> containers\n   - .for_box() for Box<T> containers\n   - .for_rc() for Rc<T> containers\n   - .for_option() for Option<T> containers\n   - .for_result() for Result<T, E> containers\n   - .with_mutex() for Mutex<T> containers (import WithContainer trait)\n   - .with_rwlock() for RwLock<T> containers (import WithContainer trait)\n   - .for_arc_mutex() for Arc<Mutex<T>> containers (with parking_lot feature)\n   - .for_arc_rwlock() for Arc<RwLock<T>> containers (with parking_lot feature)\n\nExample: let arc_keypath = my_keypath.for_arc();\nFor Mutex/RwLock: use key_paths_core::WithContainer; then my_keypath.with_mutex(&mutex, |value| { ... });\nFor Arc<Mutex>/Arc<RwLock>: let arc_mutex_keypath = my_keypath.for_arc_mutex();".to_string()
3169    } else {
3170        format!("🔧 KeyPaths Help for '{}': Use adapter methods to work with different container types. See documentation for more details.", input_str)
3171    };
3172    
3173    let expanded = quote! {
3174        compile_error!(#help_message);
3175    };
3176    
3177    TokenStream::from(expanded)
3178}