structmeta/
lib.rs

1/*!
2Parse Rust's attribute arguments by defining a struct.
3
4See [`#[derive(StructMeta)]`](macro@StructMeta) documentation for details.
5*/
6
7#[doc(hidden)]
8pub mod helpers;
9
10// mod easy_syntax;
11// pub use easy_syntax::*;
12
13mod arg_types;
14pub use arg_types::*;
15
16// #[include_doc("../../doc/to_tokens.md", start)]
17/// Derive [`quote::ToTokens`] for syntax tree node.
18///
19/// - [Example](#example)
20/// - [Helper attributes](#helper-attributes)
21///   - [`#[to_tokens("[", "]", "(", ")", "{", "}"]`](#to_tokens-----)
22///   - [`#[to_tokens(dump)]`](#to_tokensdump)
23///
24/// # Example
25///
26/// `#[derive(ToTokens)]` generates an implementation of `ToTokens` that calls [`ToTokens::to_tokens`](quote::ToTokens::to_tokens) for each field.
27///
28/// ```rust
29/// use syn::LitInt;
30///
31/// #[derive(structmeta::ToTokens)]
32/// struct Example(LitInt, LitInt);
33/// ```
34///
35/// Code like this will be generated:
36///
37/// ```rust
38/// # use syn::LitInt;
39/// # struct Example(LitInt, LitInt);
40/// impl quote::ToTokens for Example {
41///     fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
42///         self.0.to_tokens(tokens);
43///         self.1.to_tokens(tokens);
44///     }
45/// }
46/// ```
47///
48/// `#[derive(ToTokens)]` can also be specified for enum.
49///
50/// ```rust
51/// use syn::{LitInt, LitStr};
52///
53/// #[derive(structmeta::ToTokens)]
54/// enum Example {
55///     A(LitInt),
56///     B(LitStr),
57/// }
58/// ```
59///
60/// Code like this will be generated:
61///
62/// ```rust
63/// # use syn::{LitInt, LitStr};
64/// # enum Example {
65/// #    A(LitInt),
66/// #    B(LitStr),
67/// # }
68/// impl quote::ToTokens for Example {
69///     fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
70///         match self {
71///             Self::A(l) => l.to_tokens(tokens),
72///             Self::B(l) => l.to_tokens(tokens),
73///         }
74///     }
75/// }
76/// ```
77///
78/// # Helper attributes
79///
80/// |                                                             | struct | enum | varaint | field |
81/// | ----------------------------------------------------------- | ------ | ---- | ------- | ----- |
82/// | [`#[to_tokens("[")]`, `#[to_tokens("]")]`](#to_tokens-----) |        |      |         | ✔     |
83/// | [`#[to_tokens("(")]`, `#[to_tokens(")")]`](#to_tokens-----) |        |      |         | ✔     |
84/// | [`#[to_tokens("{")]`, `#[to_tokens("}")]`](#to_tokens-----) |        |      |         | ✔     |
85/// | [`#[to_tokens(dump)]`](#to_tokensdump)                      | ✔      | ✔    |         |       |
86///
87/// ## `#[to_tokens("[", "]", "(", ")", "{", "}"]`
88///
89/// By specifying `#[to_tokens("[")]` or `#[to_tokens("(")]` or `#[to_tokens("[")]` , subsequent tokens will be enclosed in `[]` or `()` or `{}`.
90///
91/// By default, all subsequent fields are enclosed.
92/// To restrict the enclosing fields, specify `#[to_tokens("]")]` or `#[to_tokens(")")]` or `#[to_tokens("}")]` for the field after the end of the enclosure.
93///
94/// ```rust
95/// use syn::{token, LitInt};
96///
97/// #[derive(structmeta::ToTokens)]
98/// struct Example {
99///     x: LitInt,
100///     #[to_tokens("[")]
101///     bracket_token: token::Bracket,
102///     y: LitInt,
103///     #[to_tokens("]")]
104///     z: LitInt,
105/// }
106/// ```
107///
108/// Code like this will be generated:
109///
110/// ```rust
111/// # use syn::{token, LitInt};
112/// #
113/// # struct Example {
114/// #    x: LitInt,
115/// #    bracket_token: token::Bracket,
116/// #    y: LitInt,
117/// #    z: LitInt,
118/// # }
119/// impl quote::ToTokens for Example {
120///     fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
121///         self.x.to_tokens(tokens);
122///         token::Bracket::surround(&self.bracket_token, tokens, |tokens| {
123///             self.y.to_tokens(tokens);
124///         });
125///         self.z.to_tokens(tokens);
126///     }
127/// }
128/// ```
129///
130/// If the field type is `Braket` or `Paren` or `Brace`, the symbol corresponding to the token type must be specified.
131///
132/// If the field type is `MacroDelimiter`, any symbol can be used and there is no difference in behavior. (Three types of parentheses are available, no matter which symbol is specified.)
133///
134/// | field type                     | start                   | end                     |
135/// | ------------------------------ | ----------------------- | ----------------------- |
136/// | [`struct@syn::token::Bracket`] | `"["`                   | `"]"`                   |
137/// | [`struct@syn::token::Paren`]   | `"("`                   | `")"`                   |
138/// | [`struct@syn::token::Brace`]   | `"{"`                   | `"}"`                   |
139/// | [`enum@syn::MacroDelimiter`]   | `"["` or `"("` or `"{"` | `"]"` or `")"` or `"}"` |
140///
141/// ## `#[to_tokens(dump)]`
142///
143/// Causes a compile error and outputs the code generated by `#[derive(ToTokens)]` as an error message.
144// #[include_doc("../../doc/to_tokens.md", end)]
145pub use structmeta_derive::ToTokens;
146
147// #[include_doc("../../doc/parse.md", start)]
148/// Derive [`syn::parse::Parse`] for syntax tree node.
149///
150/// - [Example](#example)
151/// - [Helper attributes](#helper-attributes)
152///   - [`#[to_tokens("[", "]", "(", ")", "{", "}")]`](#to_tokens-----)
153///   - [`#[parse(peek)]`](#parsepeek)
154///   - [`#[parse(any)]`](#parseany)
155///   - [`#[parse(terminated)]`](#parseterminated)
156///   - [`#[parse(dump)]`](#parsedump)
157///
158/// # Example
159///
160/// `#[derive(Parse)]` generates an implementation of `Parse` that calls [`Parse::parse`](syn::parse::Parse::parse) for each field.
161///
162/// ```rust
163/// use syn::{LitInt, LitStr};
164///
165/// #[derive(structmeta::Parse)]
166/// struct Example(LitInt, LitStr);
167/// ```
168///
169/// Code like this will be generated:
170///
171/// ```rust
172/// # use syn::{LitInt, LitStr};
173/// # struct Example(LitInt, LitStr);
174/// impl syn::parse::Parse for Example {
175///     fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
176///         let _0 = input.parse()?;
177///         let _1 = input.parse()?;
178///         return Ok(Example(_0, _1));
179///     }
180/// }
181/// ```
182///
183/// `#[derive(Parse)]` can also be specified for enum.
184///
185/// ```rust
186/// use syn::{LitInt, LitStr};
187///
188/// #[derive(structmeta::Parse)]
189/// enum Example {
190///     A(LitInt, LitInt),
191///     B(LitStr),
192/// }
193/// ```
194///
195/// Code like this will be generated:
196///
197/// ```rust
198/// # use syn::{LitInt, LitStr};
199/// # enum Example {
200/// #     A(LitInt, LitInt),
201/// #     B(LitStr),
202/// # }
203/// use syn::parse::discouraged::Speculative;
204/// impl syn::parse::Parse for Example {
205///     fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
206///         let fork = input.fork();
207///         if let Ok(value) = fork.call(|input| Ok(Example::A(input.parse()?, input.parse()?))) {
208///             input.advance_to(&fork);
209///             return Ok(value);
210///         }
211///
212///         let fork = input.fork();
213///         if let Ok(value) = fork.call(|input| Ok(Example::B(input.parse()?))) {
214///             input.advance_to(&fork);
215///             return Ok(value);
216///         }
217///
218///         Err(input.error("parse failed."))
219///     }
220/// }
221/// ```
222///
223/// # Helper attributes
224///
225/// |                                                                 | struct | enum | varaint | field |
226/// | --------------------------------------------------------------- | ------ | ---- | ------- | ----- |
227/// | [`#[to_tokens("[", "]", "(", ")", "{", "}")]`](#to_tokens-----) |        |      |         | ✔     |
228/// | [`#[parse(peek)]`](#parsepeek)                                  |        |      |         | ✔     |
229/// | [`#[parse(any)]`](#parseany)                                    |        |      |         | ✔     |
230/// | [`#[parse(terminated)]`](#parseterminated)                      |        |      |         | ✔     |
231/// | [`#[parse(dump)]`](#parsedump)                                  | ✔      | ✔    |         |       |
232///
233/// ## `#[to_tokens("[", "]", "(", ")", "{", "}")]`
234///
235/// By specifying `#[to_tokens("[")]` or `#[to_tokens("(")]` or `#[to_tokens("[")]` , subsequent tokens will be enclosed in `[]` or `()` or `{}`.
236///
237/// By default, all subsequent fields are enclosed.
238/// To restrict the enclosing fields, specify `#[to_tokens("]")]` or `#[to_tokens(")")]` or `#[to_tokens("}")]` for the field after the end of the enclosure.
239///
240/// ```rust
241/// use syn::{token, LitInt};
242///
243/// #[derive(structmeta::Parse)]
244/// struct Example {
245///     x: LitInt,
246///     #[to_tokens("[")]
247///     bracket_token: token::Bracket,
248///     y: LitInt,
249///     #[to_tokens("]")]
250///     z: LitInt,
251/// }
252/// ```
253///
254/// Code like this will be generated:
255///
256/// ```rust
257/// # use syn::{token, LitInt};
258/// #
259/// # struct Example {
260/// #    x: LitInt,
261/// #    bracket_token: token::Bracket,
262/// #    y: LitInt,
263/// #    z: LitInt,
264/// # }
265/// impl syn::parse::Parse for Example {
266///     fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
267///         let x = input.parse()?;
268///         let content;
269///         let bracket_token = syn::bracketed!(content in input);
270///         let y = content.parse()?;
271///         let z = input.parse()?;
272///         Ok(Self {
273///             x,
274///             bracket_token,
275///             y,
276///             z,
277///         })
278///     }
279/// }
280/// ```
281///
282/// If the field type is `Braket` or `Paren` or `Brace`, the symbol corresponding to the token type must be specified.
283///
284/// If the field type is `MacroDelimiter`, any symbol can be used and there is no difference in behavior. (Three types of parentheses are available, no matter which symbol is specified.)
285///
286/// | field type                     | start                   | end                     |
287/// | ------------------------------ | ----------------------- | ----------------------- |
288/// | [`struct@syn::token::Bracket`] | `"["`                   | `"]"`                   |
289/// | [`struct@syn::token::Paren`]   | `"("`                   | `")"`                   |
290/// | [`struct@syn::token::Brace`]   | `"{"`                   | `"}"`                   |
291/// | [`enum@syn::MacroDelimiter`]   | `"["` or `"("` or `"{"` | `"]"` or `")"` or `"}"` |
292///
293/// ## `#[parse(peek)]`
294///
295/// When parsing an enum, it will peek the field with this attribute set,
296/// and if successful, will parse the variant containing the field.
297/// If the peek succeeds, the subsequent variant will not be parsed even if the parse failed.
298///
299/// Variant where `#[parse(peek)]` is not specified will fork input and parse.
300///
301/// If the peek fails or the parsing of the forked input fails, the subsequent variant will be parsed.
302///
303/// ```rust
304/// use syn::{LitInt, LitStr};
305/// #[derive(structmeta::Parse)]
306/// enum Example {
307///     A(#[parse(peek)] LitInt, LitInt),
308///     B(LitStr),
309/// }
310/// ```
311///
312/// Code like this will be generated:
313///
314/// ```rust
315/// # use syn::{LitInt, LitStr};
316/// # enum Example {
317/// #     A(LitInt, LitInt),
318/// #     B(LitStr),
319/// # }
320/// impl syn::parse::Parse for Example {
321///     fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
322///         if input.peek(LitInt) {
323///             let a_0 = input.parse()?;
324///             let a_1 = input.parse()?;
325///             return Ok(Example::A(a_0, a_1));
326///         }
327///         let b_0 = input.parse()?;
328///         Ok(Example::B(b_0))
329///     }
330/// }
331/// ```
332///
333/// `#[parse(peek)]` can be specified on the first three `TokenTree` for each variant.
334///
335/// ```rust
336/// use syn::{LitInt, LitStr};
337/// #[derive(structmeta::Parse)]
338/// enum Example {
339///     A(#[parse(peek)] LitInt, #[parse(peek)]LitInt, #[parse(peek)]LitInt),
340///     B(#[parse(peek)] LitStr),
341/// }
342/// ```
343///
344/// Since the tokens enclosed by the delimiter is treated as a single token tree, you can also specify `#[parse(peek)]` to the field with `#[to_tokens("]")]`, `#[to_tokens("}")]`, `#[to_tokens(")")]`.
345///
346/// ```rust
347/// use syn::{token, LitInt, LitStr};
348/// #[derive(structmeta::Parse)]
349/// enum Example {
350///     A {
351///         #[parse(peek)]
352///         #[to_tokens("{")]
353///         a: token::Brace,
354///         b: LitInt,
355///         c: LitInt,
356///         #[to_tokens("}")]
357///         #[parse(peek)]
358///         d: LitInt,
359///     },
360/// }
361/// ```
362///
363/// To use `#[parse(peek)]` for a field that type is `Ident`, use `syn::Ident` insted of `proc_macro2::Ident`.
364///
365/// ```compile_fail
366/// #[derive(structmeta::Parse)]
367/// enum ExampleNg {
368///     A(#[parse(peek)] proc_macro2::Ident),
369/// }
370/// ```
371///
372/// ```rust
373/// #[derive(structmeta::Parse)]
374/// enum ExampleOk {
375///     A(#[parse(peek)] syn::Ident),
376/// }
377/// ```
378///
379/// ## `#[parse(any)]`
380///
381/// When parsing `Ident`, allow values that cannot be used as identifiers, such as keywords.
382///
383/// In other words, `Ident::parse_any` and `Ident::peek_any` was generated instead of `Ident::parse` and `Ident::peek`.
384///
385/// ```rust
386/// use quote::quote;
387/// use structmeta::Parse;
388/// use syn::{parse2, Ident};
389///
390/// #[derive(Parse)]
391/// struct WithAny(#[parse(any)] Ident);
392///
393/// #[derive(Parse)]
394/// struct WithoutAny(Ident);
395///
396/// assert_eq!(parse2::<WithAny>(quote!(self)).is_ok(), true);
397/// assert_eq!(parse2::<WithoutAny>(quote!(self)).is_ok(), false);
398/// ```
399///
400/// ## `#[parse(terminated)]`
401///
402/// Use [`Punctuated::parse_terminated`](syn::punctuated::Punctuated::parse_terminated) to parse.
403///
404/// ```rust
405/// use quote::quote;
406/// use structmeta::Parse;
407/// use syn::{parse2, punctuated::Punctuated, Ident, Token};
408/// #[derive(Parse)]
409/// struct Example(#[parse(terminated)] Punctuated<Ident, Token![,]>);
410/// assert_eq!(parse2::<Example>(quote!(a, b, c)).is_ok(), true);
411/// ```
412///
413/// `terminated` can also be used with `any`.
414///
415/// ```rust
416/// use quote::quote;
417/// use structmeta::Parse;
418/// use syn::{parse2, punctuated::Punctuated, Ident, Token};
419///
420/// #[derive(Parse)]
421/// struct WithAny(#[parse(terminated, any)] Punctuated<Ident, Token![,]>);
422///
423/// #[derive(Parse)]
424/// struct WithoutAny(#[parse(terminated)] Punctuated<Ident, Token![,]>);
425///
426/// assert_eq!(parse2::<WithAny>(quote!(self, self)).is_ok(), true);
427/// assert_eq!(parse2::<WithoutAny>(quote!(self, self)).is_ok(), false);
428/// ```
429///
430/// ## `#[parse(dump)]`
431///
432/// Causes a compile error and outputs the code generated by `#[derive(Parse)]` as an error message.
433// #[include_doc("../../doc/parse.md", end)]
434pub use structmeta_derive::Parse;
435
436// #[include_doc("../../doc/struct_meta.md", start)]
437/// Derive [`syn::parse::Parse`] for parsing attribute arguments.
438///
439/// - [Example](#example)
440/// - [Named parameter](#named-parameter)
441///   - [Supported field types for named parameter](#supported-field-types-for-named-parameter)
442///   - [Flag style](#flag-style)
443///   - [NameValue style](#namevalue-style)
444///   - [NameArgs style](#nameargs-style)
445///   - [NameArgs or Flag style](#nameargs-or-flag-style)
446///   - [NameArgList style](#namearglist-style)
447///   - [NameArgList or Flag style](#namearglist-or-flag-style)
448///   - [Optional named parameter](#optional-named-parameter)
449///   - [Rest named parameter](#rest-named-parameter)
450/// - [Unnamed parameter](#unnamed-parameter)
451///   - [Required unnamed parameter](#required-unnamed-parameter)
452///   - [Optional unnamed parameter](#optional-unnamed-parameter)
453///   - [Variadic unnamed parameter](#variadic-unnamed-parameter)
454/// - [Parameter order](#parameter-order)
455/// - [Helper attribute `#[struct_meta(...)]`](#helper-attribute-struct_meta)
456/// - [Uses with `#[proc_macro_derive]`](#uses-with-proc_macro_derive)
457/// - [Uses with `#[proc_macro_attribute]`](#uses-with-proc_macro_attribute)
458/// - [Parsing ambiguous arguments](#parsing-ambiguous-arguments)
459///   - [`#[struct_meta(name_filter = "...")]`](#struct_metaname_filter--)
460///
461/// # Example
462///
463/// ```rust
464/// use structmeta::StructMeta;
465/// use syn::{parse_quote, Attribute};
466/// use syn::{LitInt, LitStr};
467///
468/// #[derive(StructMeta)]
469/// struct Args {
470///     #[struct_meta(unnamed)]
471///     a: LitStr,
472///     b: LitInt,
473///     c: Option<LitInt>,
474/// }
475///
476/// let attr: Attribute = parse_quote!(#[attr("xyz", b = 10)]);
477/// let args: Args = attr.parse_args()?;
478/// assert_eq!(args.a.value(), "xyz");
479/// assert_eq!(args.b.base10_parse::<u32>()?, 10);
480/// assert!(args.c.is_none());
481/// # syn::Result::Ok(())
482/// ```
483///
484/// # Named parameter
485///
486/// The following field will be "Named parameter".
487///
488/// - field in record struct.
489/// - field with `#[struct_meta(name = "...")]` in tuple struct.
490/// - However, fields that meet the following conditions are excluded
491///   - field with `#[struct_meta(unnamed)]`
492///   - field with type `HashMap<String, _>`
493///
494/// "Named parameter" is a parameter that specifies with a name, such as `#[attr(flag, x = 10, y(1, 2, 3))]`.
495///
496/// ## Supported field types for named parameter
497///
498/// "Named parameter" has the following four styles, and the style is determined by the type of the field.
499///
500/// - Flag style : `name`
501/// - NameValue style : `name = value`
502/// - NameArgs style : `name(args)`
503/// - NameArgList style : `name(arg, arg, ...)`
504///
505/// | field type | field type (with span)       | style                                             | example                         |
506/// | ---------- | ---------------------------- | ------------------------------------------------- | ------------------------------- |
507/// | `bool`     | [`Flag`]                     | [Flag](#flag-style)                               | `name`                          |
508/// | `T`        | [`NameValue<T>`]             | [NameValue](#namevalue-style)                     | `name = value`                  |
509/// |            | [`NameArgs<T>`]              | [NameArgs](#nameargs-or-flag-style)               | `name(args)`                    |
510/// |            | [`NameArgs<Option<T>>`]      | [NameArgs or Flag](#nameargs-or-flag-style)       | `name(args)` or `name`          |
511/// | `Vec<T>`   | [`NameArgs<Vec<T>>`]         | [NameArgList](#namearglist-style)                 | `name(arg, arg, ...)`           |
512/// |            | [`NameArgs<Option<Vec<T>>>`] | [NameArgList or Flag](#namearglist-or-flag-style) | `name(arg, arg, ...)` or `name` |
513///
514/// Note: the type `T` in the table above needs to implement `syn::parse::Parse`.
515///
516/// With the above type as P (`bool` and `Flag` are excluded), you can also use the following types.
517///
518/// | field type           | effect                                          |
519/// | -------------------- | ----------------------------------------------- |
520/// | `Option<P>`          | [optional parameter](#optional-named-parameter) |
521/// | `HashMap<String, P>` | [rest parameter](#rest-named-parameter)         |
522///
523/// ## Flag style
524///
525/// A field with the type `bool` will be a parameter that specifies only its name.
526///
527/// ```rust
528/// use structmeta::StructMeta;
529/// use syn::{parse_quote, Attribute};
530///
531/// #[derive(StructMeta)]
532/// struct Args {
533///     a: bool,
534///     b: bool,
535/// }
536///
537/// let attr: Attribute = parse_quote!(#[attr(a)]);
538/// let args: Args = attr.parse_args()?;
539/// assert_eq!(args.a, true);
540/// assert_eq!(args.b, false);
541///
542/// let attr: Attribute = parse_quote!(#[attr(a, b)]);
543/// let args: Args = attr.parse_args()?;
544/// assert_eq!(args.a, true);
545/// assert_eq!(args.b, true);
546/// # syn::Result::Ok(())
547/// ```
548///
549/// If you use `Flag` instead of `bool`, you will get its `Span` when the argument is specified.
550///
551/// ```rust
552/// use structmeta::{Flag, StructMeta};
553/// use syn::{parse_quote, Attribute};
554///
555/// #[derive(StructMeta)]
556/// struct Args {
557///     a: Flag,
558/// }
559///
560/// let attr: Attribute = parse_quote!(#[attr(a)]);
561/// let args: Args = attr.parse_args()?;
562/// if let Some(_span) = args.a.span {
563///     // Use span.
564/// }
565/// # syn::Result::Ok(())
566/// ```
567///
568/// ## NameValue style
569///
570/// A field with type `T` or `NameValue<T>` will be `name = value` style parameter.
571///
572/// ```rust
573/// use structmeta::{NameValue, StructMeta};
574/// use syn::{parse_quote, Attribute, LitInt, LitStr};
575///
576/// #[derive(StructMeta)]
577/// struct Args {
578///     a: LitStr,
579///     b: NameValue<LitInt>,
580/// }
581///
582/// let attr: Attribute = parse_quote!(#[attr(a = "abc", b = 10)]);
583/// let args: Args = attr.parse_args()?;
584/// assert_eq!(args.a.value(), "abc");
585/// assert_eq!(args.b.value.base10_parse::<u32>()?, 10);
586/// # syn::Result::Ok(())
587/// ```
588///
589/// ## NameArgs style
590///
591/// A field with type `NameArgs<T>` will be `name(args)` style parameter.
592///
593/// ```rust
594/// use structmeta::{NameArgs, StructMeta};
595/// use syn::{parse_quote, Attribute, LitInt, LitStr};
596///
597/// #[derive(StructMeta)]
598/// struct Args {
599///     a: NameArgs<LitStr>,
600///     b: NameArgs<LitInt>,
601/// }
602///
603/// let attr: Attribute = parse_quote!(#[attr(a("abc"), b(10))]);
604/// let args: Args = attr.parse_args()?;
605/// assert_eq!(args.a.args.value(), "abc");
606/// assert_eq!(args.b.args.base10_parse::<u32>()?, 10);
607/// # syn::Result::Ok(())
608/// ```
609///
610/// ## NameArgs or Flag style
611///
612/// A field with type `NameArgs<T>` will be `name(args)` or `name` style parameter.
613///
614/// ```rust
615/// use structmeta::{NameArgs, StructMeta};
616/// use syn::{parse_quote, Attribute, LitInt, LitStr};
617///
618/// #[derive(StructMeta)]
619/// struct Args {
620///     a: NameArgs<Option<LitStr>>,
621///     b: NameArgs<Option<LitInt>>,
622/// }
623///
624/// let attr: Attribute = parse_quote!(#[attr(a, b(10))]);
625/// let args: Args = attr.parse_args()?;
626/// assert!(args.a.args.is_none());
627/// assert_eq!(args.b.args.unwrap().base10_parse::<u32>()?, 10);
628/// # syn::Result::Ok(())
629/// ```
630///
631/// ## NameArgList style
632///
633/// A field with type `NameArgs<Vec<T>>` will be `name(arg, arg, ...)` style parameter.
634///
635/// ```rust
636/// use structmeta::{NameArgs, StructMeta};
637/// use syn::{parse_quote, Attribute, LitStr};
638///
639/// #[derive(StructMeta)]
640/// struct Args {
641///     a: NameArgs<Vec<LitStr>>,
642/// }
643///
644/// let attr: Attribute = parse_quote!(#[attr(a())]);
645/// let args: Args = attr.parse_args()?;
646/// assert_eq!(args.a.args.len(), 0);
647///
648/// let attr: Attribute = parse_quote!(#[attr(a("x"))]);
649/// let args: Args = attr.parse_args()?;
650/// assert_eq!(args.a.args.len(), 1);
651///
652/// let attr: Attribute = parse_quote!(#[attr(a("x", "y"))]);
653/// let args: Args = attr.parse_args()?;
654/// assert_eq!(args.a.args.len(), 2);
655/// # syn::Result::Ok(())
656/// ```
657///
658/// ## NameArgList or Flag style
659///
660/// A field with type `NameArgs<Option<Vec<T>>>` will be `name(arg, arg, ...)` or `name` style parameter.
661///
662/// ```rust
663/// use structmeta::{NameArgs, StructMeta};
664/// use syn::{parse_quote, Attribute, LitStr};
665///
666/// #[derive(StructMeta)]
667/// struct Args {
668///     abc: NameArgs<Option<Vec<LitStr>>>,
669/// }
670///
671/// let attr: Attribute = parse_quote!(#[attr(abc)]);
672/// let args: Args = attr.parse_args()?;
673/// assert_eq!(args.abc.args.is_none(), true);
674///
675/// let attr: Attribute = parse_quote!(#[attr(abc())]);
676/// let args: Args = attr.parse_args()?;
677/// assert_eq!(args.abc.args.unwrap().len(), 0);
678///
679/// let attr: Attribute = parse_quote!(#[attr(abc("x"))]);
680/// let args: Args = attr.parse_args()?;
681/// assert_eq!(args.abc.args.unwrap().len(), 1);
682///
683/// let attr: Attribute = parse_quote!(#[attr(abc("x", "y"))]);
684/// let args: Args = attr.parse_args()?;
685/// assert_eq!(args.abc.args.unwrap().len(), 2);
686/// # syn::Result::Ok(())
687/// ```
688///
689/// ## Optional named parameter
690///
691/// If you use `Option` for the field type, it becomes an optional parameter.
692///
693/// ```rust
694/// use structmeta::{NameValue, StructMeta};
695/// use syn::{parse_quote, Attribute, LitInt, LitStr};
696///
697/// #[derive(StructMeta)]
698/// struct Args {
699///     a: Option<LitStr>,
700///     b: Option<NameValue<LitInt>>,
701/// }
702///
703/// let attr: Attribute = parse_quote!(#[attr(a = "abc")]);
704/// let args: Args = attr.parse_args()?;
705/// assert!(args.a.is_some());
706/// assert!(args.b.is_none());
707///
708/// let attr: Attribute = parse_quote!(#[attr(b = 10)]);
709/// let args: Args = attr.parse_args()?;
710/// assert!(args.a.is_none());
711/// assert!(args.b.is_some());
712/// # syn::Result::Ok(())
713/// ```
714///
715/// ## Rest named parameter
716///
717/// If `HashMap<String, _>` is used for the field type, the field will contain named arguments that are not associated with the field.
718///
719/// ```rust
720/// use std::collections::HashMap;
721/// use structmeta::StructMeta;
722/// use syn::{parse_quote, Attribute, LitInt};
723///
724/// #[derive(StructMeta)]
725/// struct Args {
726///     a: Option<LitInt>,
727///     rest: HashMap<String, LitInt>,
728/// }
729///
730/// let attr: Attribute = parse_quote!(#[attr(a = 10, b = 20, c = 30)]);
731/// let args: Args = attr.parse_args()?;
732/// assert!(args.a.is_some());
733/// let mut keys: Vec<_> = args.rest.keys().collect();
734/// keys.sort();
735/// assert_eq!(keys, vec!["b", "c"]);
736/// # syn::Result::Ok(())
737/// ```
738///
739/// # Unnamed parameter
740///
741/// The following field will be "Unnamed parameter".
742///
743/// - field in tuple struct.
744/// - field with `#[struct_meta(unnamed)]` in record struct.
745/// - However, fields that meet the following conditions are excluded
746///   - field with `#[struct_meta(name = "...")]`
747///   - field with type `HashMap<String, _>`
748///
749/// "Unnamed parameter" is a value-only parameter, such as `#[attr("abc", 10, 20)]`.
750///
751/// | field type  | effect                                            |
752/// | ----------- | ------------------------------------------------- |
753/// | `T`         | [required parameter](#required-unnamed-parameter) |
754/// | `Option<T>` | [optional parameter](#optional-unnamed-parameter) |
755/// | `Vec<T>`    | [variadic parameter](#variadic-unnamed-parameter) |
756///
757/// The type `T` in the table above needs to implement `syn::parse::Parse`.
758///
759/// ## Required unnamed parameter
760///
761/// Fields of the type that implement `syn::parse::Parse` will be required parameters.
762///
763/// ```rust
764/// use structmeta::StructMeta;
765/// use syn::{parse_quote, Attribute, LitStr, Result};
766///
767/// #[derive(StructMeta)]
768/// struct Args(LitStr);
769///
770/// let attr: Attribute = parse_quote!(#[attr()]);
771/// let args: Result<Args> = attr.parse_args();
772/// assert!(args.is_err());
773///
774/// let attr: Attribute = parse_quote!(#[attr("a")]);
775/// let args: Args = attr.parse_args()?;
776/// assert_eq!(args.0.value(), "a");
777/// # syn::Result::Ok(())
778/// ```
779///
780/// ## Optional unnamed parameter
781///
782/// Fields of type `Option` will be optional parameters.
783///
784/// ```rust
785/// use structmeta::StructMeta;
786/// use syn::{parse_quote, Attribute, LitStr};
787///
788/// #[derive(StructMeta)]
789/// struct Args(Option<LitStr>);
790///
791/// let attr: Attribute = parse_quote!(#[attr()]);
792/// let args: Args = attr.parse_args()?;
793/// assert!(args.0.is_none());
794///
795/// let attr: Attribute = parse_quote!(#[attr("a")]);
796/// let args: Args = attr.parse_args()?;
797/// assert_eq!(args.0.unwrap().value(), "a");
798/// # syn::Result::Ok(())
799/// ```
800///
801/// ## Variadic unnamed parameter
802///
803/// If you use `Vec` as the field type, multiple arguments can be stored in a single field.
804///
805/// ```rust
806/// use structmeta::StructMeta;
807/// use syn::{parse_quote, Attribute, LitStr};
808///
809/// #[derive(StructMeta)]
810/// struct Args(Vec<LitStr>);
811///
812/// let attr: Attribute = parse_quote!(#[attr()]);
813/// let args: Args = attr.parse_args()?;
814/// assert_eq!(args.0.len(), 0);
815///
816/// let attr: Attribute = parse_quote!(#[attr("a")]);
817/// let args: Args = attr.parse_args()?;
818/// assert_eq!(args.0.len(), 1);
819/// assert_eq!(args.0[0].value(), "a");
820///
821/// let attr: Attribute = parse_quote!(#[attr("a", "b")]);
822/// let args: Args = attr.parse_args()?;
823/// assert_eq!(args.0.len(), 2);
824/// assert_eq!(args.0[0].value(), "a");
825/// assert_eq!(args.0[1].value(), "b");
826/// # syn::Result::Ok(())
827/// ```
828///
829/// # Parameter order
830///
831/// The parameters must be in the following order.
832///
833/// - Unnamed
834///   - Required
835///   - Optional
836///   - Variadic
837/// - Named
838///
839/// # Helper attribute `#[struct_meta(...)]`
840///
841/// | argument                                           | struct | field | effect                                                                                   |
842/// | -------------------------------------------------- | ------ | ----- | ---------------------------------------------------------------------------------------- |
843/// | `dump`                                             | ✔      |       | Causes a compile error and outputs the automatically generated code as an error message. |
844/// | [`name_filter = "..."`](#struct_metaname_filter--) | ✔      |       | Specify how to distinguish between a parameter name and a value of an unnamed parameter. |
845/// | `name = "..."`                                     |        | ✔     | Specify a parameter name.                                                                |
846/// | `unnamed`                                          |        | ✔     | Make the field be treated as an unnamed parameter.                                       |
847///
848/// # Uses with `#[proc_macro_derive]`
849///
850/// A type with `#[derive(StructMeta)]` can be used with [`syn::Attribute::parse_args`].
851///
852/// ```rust
853/// # extern crate proc_macro;
854/// use proc_macro::TokenStream;
855/// use quote::quote;
856/// use structmeta::StructMeta;
857/// use syn::{parse, parse_macro_input, DeriveInput, LitStr};
858///
859/// #[derive(StructMeta)]
860/// struct MyAttr {
861///     msg: LitStr,
862/// }
863///
864/// # const IGNORE_TOKENS: &str = stringify! {
865/// #[proc_macro_derive(MyMsg, attributes(my_msg))]
866/// # };
867/// pub fn derive_my_msg(input: TokenStream) -> TokenStream {
868///     let input = parse_macro_input!(input as DeriveInput);
869///     let mut msg = String::new();
870///     for attr in input.attrs {
871///         if attr.path.is_ident("my_msg") {
872///             let attr = attr.parse_args::<MyAttr>().unwrap();
873///             msg = attr.msg.value();
874///         }
875///     }
876///     quote!(const MSG: &str = #msg;).into()
877/// }
878/// ```
879///
880/// ```ignore
881/// #[derive(MyMsg)]
882/// #[my_msg(msg = "abc")]
883/// struct TestType;
884///
885/// assert_eq!(MSG, "abc");
886/// ```
887///
888/// # Uses with `#[proc_macro_attribute]`
889///
890/// A type with `#[derive(StructMeta)]` can be used with `attr` parameter in attribute proc macro.
891///
892/// ```rust
893/// # extern crate proc_macro;
894/// use proc_macro::TokenStream;
895/// use quote::quote;
896/// use structmeta::StructMeta;
897/// use syn::{parse, parse_macro_input, DeriveInput, LitStr};
898///
899/// #[derive(StructMeta)]
900/// struct MyAttr {
901///     msg: LitStr,
902/// }
903/// # const IGNORE_TOKENS: &str = stringify! {
904/// #[proc_macro_attribute]
905/// # };
906/// pub fn my_attr(attr: TokenStream, _item: TokenStream) -> TokenStream {
907///     let attr = parse::<MyAttr>(attr).unwrap();
908///     let msg = attr.msg.value();
909///     quote!(const MSG: &str = #msg;).into()
910/// }
911/// ```
912///
913/// ```ignore
914/// #[my_attr(msg = "xyz")]
915/// struct TestType;
916///
917/// assert_eq!(MSG, "xyz");
918/// ```
919///
920/// # Parsing ambiguous arguments
921///
922/// If one or more `name = value` style parameters are defined, arguments beginning with `name =` will be parsed as `name = value` style,
923/// even if the name is different from what it is defined as.
924///
925/// This specification is intended to prevent `name = value` from being treated as unnamed parameter due to typo.
926///
927/// ```rust
928/// use structmeta::StructMeta;
929/// use syn::{parse_quote, Attribute, Expr, LitInt, Result};
930///
931/// #[derive(StructMeta)]
932/// struct WithNamed {
933///     #[struct_meta(unnamed)]
934///     unnamed: Option<Expr>,
935///     x: Option<LitInt>,
936/// }
937///
938/// let attr_x: Attribute = parse_quote!(#[attr(x = 10)]);
939/// let result: WithNamed = attr_x.parse_args().unwrap();
940/// assert_eq!(result.unnamed.is_some(), false);
941/// assert_eq!(result.x.is_some(), true);
942///
943/// // `y = 10` is parsed as a wrong named parameter.
944/// let attr_y: Attribute = parse_quote!(#[attr(y = 10)]);
945/// let result: Result<WithNamed> = attr_y.parse_args();
946/// assert!(result.is_err());
947/// ```
948///
949/// If `name = value` style parameter is not defined, it will be parsed as unnamed parameter.
950///
951/// ```rust
952/// use structmeta::StructMeta;
953/// use syn::{parse_quote, Attribute, Expr, LitInt, Result};
954///
955/// #[derive(StructMeta)]
956/// struct WithoutNamed {
957///     #[struct_meta(unnamed)]
958///     unnamed: Option<Expr>,
959/// }
960///
961/// // `y = 10` is parsed as a unnamed parameter.
962/// let attr_y: Attribute = parse_quote!(#[attr(y = 10)]);
963/// let result: WithoutNamed = attr_y.parse_args().unwrap();
964/// assert_eq!(result.unnamed, Some(parse_quote!(y = 10)));
965/// ```
966///
967/// Similarly, if one or more `name(args)` style parameters are defined, arguments with `name(args)` will be parsed as `name(args)` style.
968/// If `name(args)` style parameter is not defined, it will be parsed as unnamed parameter.
969///
970/// The same is true for `name` or `name = value` style parameter.
971///
972/// ## `#[struct_meta(name_filter = "...")]`
973///
974/// By attaching `#[struct_meta(name_filter = "...")]` to struct definition, you can restrict the names that can be used as parameter names and treat other identifiers as a value of unnamed parameter.
975///
976/// The following value can be used.
977///
978/// - `"snake_case"`
979///
980/// ```rust
981/// use structmeta::StructMeta;
982/// use syn::{parse_quote, Attribute, Expr, LitInt, Result};
983///
984/// let attr_x: Attribute = parse_quote!(#[attr(X)]);
985/// let attr_y: Attribute = parse_quote!(#[attr(Y)]);
986///
987/// #[derive(StructMeta)]
988/// struct NoFilter {
989///     #[struct_meta(unnamed)]
990///     unnamed: Option<Expr>,
991///     #[struct_meta(name = "X")]
992///     x: bool,
993/// }
994/// let result: NoFilter = attr_x.parse_args().unwrap();
995/// assert_eq!(result.unnamed, None);
996/// assert_eq!(result.x, true); // `X` is parsed as a named parameter.
997///
998/// let result: Result<NoFilter> = attr_y.parse_args();
999/// assert!(result.is_err()); // `Y` is parsed as a wrong named parameter.
1000///
1001///
1002/// #[derive(StructMeta)]
1003/// #[struct_meta(name_filter = "snake_case")]
1004/// struct WithFilter {
1005///     #[struct_meta(unnamed)]
1006///     unnamed: Option<Expr>,
1007///     #[struct_meta(name = "X")]
1008///     x: bool,
1009/// }
1010/// let result: WithFilter = attr_x.parse_args().unwrap();
1011/// assert_eq!(result.unnamed, Some(parse_quote!(X))); // `X` is parsed as a unnamed parameter.
1012/// assert_eq!(result.x, false);
1013/// ```
1014// #[include_doc("../../doc/struct_meta.md", end)]
1015pub use structmeta_derive::StructMeta;