Parses a field name, which can be either an identifier or a numeric index. # Examples - `name` → `FieldName::Ident("name")` - `0` → `FieldName::Index(0)` - `42` → `FieldName::Index(42)` # Note on consecutive indices Due to proc macro tokenization, consecutive numeric indices like `.0.0` are tokenized as a float literal after the first dot is consumed. This is a known limitation - use tuple destr
(input: syn::parse::ParseStream)
| 53 | /// are tokenized as a float literal after the first dot is consumed. |
| 54 | /// This is a known limitation - use tuple destructuring syntax instead. |
| 55 | fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> { |
| 56 | // Try to parse as a numeric literal first using fork |
| 57 | let fork = input.fork(); |
| 58 | if let Ok(lit) = fork.parse::<syn::LitInt>() { |
| 59 | // Successfully parsed as number, consume from real input |
| 60 | let _: syn::LitInt = input.parse()?; |
| 61 | let index = lit.base10_parse()?; |
| 62 | Ok(FieldName::Index(index)) |
| 63 | } else { |
| 64 | // Try parsing as identifier |
| 65 | input |
| 66 | .parse::<syn::Ident>() |
| 67 | .map(FieldName::Ident) |
| 68 | .map_err(|_| { |
| 69 | syn::Error::new( |
| 70 | input.span(), |
| 71 | "expected field name (identifier or numeric index)", |
| 72 | ) |
| 73 | }) |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | /// Field assertion - field operations paired with an expected pattern |
no test coverage detected