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 | variant | 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 `Bracket` 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 | variant | 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 `Bracket` 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` instead 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/// - [NameValue or Flag style](#namevalue-or-flag-style)
445/// - [NameArgs style](#nameargs-style)
446/// - [NameArgs or Flag style](#nameargs-or-flag-style)
447/// - [NameArgList style](#namearglist-style)
448/// - [NameArgList or Flag style](#namearglist-or-flag-style)
449/// - [Optional named parameter](#optional-named-parameter)
450/// - [Rest named parameter](#rest-named-parameter)
451/// - [Unnamed parameter](#unnamed-parameter)
452/// - [Required unnamed parameter](#required-unnamed-parameter)
453/// - [Optional unnamed parameter](#optional-unnamed-parameter)
454/// - [Variadic unnamed parameter](#variadic-unnamed-parameter)
455/// - [Parameter order](#parameter-order)
456/// - [Helper attribute `#[struct_meta(...)]`](#helper-attribute-struct_meta)
457/// - [Uses with `#[proc_macro_derive]`](#uses-with-proc_macro_derive)
458/// - [Uses with `#[proc_macro_attribute]`](#uses-with-proc_macro_attribute)
459/// - [Parsing ambiguous arguments](#parsing-ambiguous-arguments)
460/// - [`#[struct_meta(name_filter = "...")]`](#struct_metaname_filter--)
461///
462/// # Example
463///
464/// ```rust
465/// use structmeta::StructMeta;
466/// use syn::{parse_quote, Attribute};
467/// use syn::{LitInt, LitStr};
468///
469/// #[derive(StructMeta)]
470/// struct Args {
471/// #[struct_meta(unnamed)]
472/// a: LitStr,
473/// b: LitInt,
474/// c: Option<LitInt>,
475/// }
476///
477/// let attr: Attribute = parse_quote!(#[attr("xyz", b = 10)]);
478/// let args: Args = attr.parse_args()?;
479/// assert_eq!(args.a.value(), "xyz");
480/// assert_eq!(args.b.base10_parse::<u32>()?, 10);
481/// assert!(args.c.is_none());
482/// # syn::Result::Ok(())
483/// ```
484///
485/// # Named parameter
486///
487/// The following field will be "Named parameter".
488///
489/// - field in record struct.
490/// - field with `#[struct_meta(name = "...")]` in tuple struct.
491/// - However, fields that meet the following conditions are excluded
492/// - field with `#[struct_meta(unnamed)]`
493/// - field with type `HashMap<String, _>`
494///
495/// "Named parameter" is a parameter that specifies with a name, such as `#[attr(flag, x = 10, y(1, 2, 3))]`.
496///
497/// ## Supported field types for named parameter
498///
499/// "Named parameter" has the following four styles, and the style is determined by the type of the field.
500///
501/// - Flag style : `name`
502/// - NameValue style : `name = value`
503/// - NameArgs style : `name(args)`
504/// - NameArgList style : `name(arg, arg, ...)`
505///
506/// | field type | field type (with span) | style | example |
507/// | ---------- | ---------------------------- | ------------------------------------------------- | ------------------------------- |
508/// | `bool` | [`Flag`] | [Flag](#flag-style) | `name` |
509/// | `T` | [`NameValue<T>`] | [NameValue](#namevalue-style) | `name = value` |
510/// | | [`NameValue<Option<T>>`] | [NameValue or Flag](#namevalue-or-flag-style) | `name = value` or `name` |
511/// | | [`NameArgs<T>`] | [NameArgs](#nameargs-or-flag-style) | `name(args)` |
512/// | | [`NameArgs<Option<T>>`] | [NameArgs or Flag](#nameargs-or-flag-style) | `name(args)` or `name` |
513/// | `Vec<T>` | [`NameArgs<Vec<T>>`] | [NameArgList](#namearglist-style) | `name(arg, arg, ...)` |
514/// | | [`NameArgs<Option<Vec<T>>>`] | [NameArgList or Flag](#namearglist-or-flag-style) | `name(arg, arg, ...)` or `name` |
515///
516/// Note: the type `T` in the table above needs to implement `syn::parse::Parse`.
517///
518/// With the above type as P (`bool` and `Flag` are excluded), you can also use the following types.
519///
520/// | field type | effect |
521/// | -------------------- | ----------------------------------------------- |
522/// | `Option<P>` | [optional parameter](#optional-named-parameter) |
523/// | `HashMap<String, P>` | [rest parameter](#rest-named-parameter) |
524///
525/// ## Flag style
526///
527/// A field with the type `bool` will be a parameter that specifies only its name.
528///
529/// ```rust
530/// use structmeta::StructMeta;
531/// use syn::{parse_quote, Attribute};
532///
533/// #[derive(StructMeta)]
534/// struct Args {
535/// a: bool,
536/// b: bool,
537/// }
538///
539/// let attr: Attribute = parse_quote!(#[attr(a)]);
540/// let args: Args = attr.parse_args()?;
541/// assert_eq!(args.a, true);
542/// assert_eq!(args.b, false);
543///
544/// let attr: Attribute = parse_quote!(#[attr(a, b)]);
545/// let args: Args = attr.parse_args()?;
546/// assert_eq!(args.a, true);
547/// assert_eq!(args.b, true);
548/// # syn::Result::Ok(())
549/// ```
550///
551/// If you use `Flag` instead of `bool`, you will get its `Span` when the argument is specified.
552///
553/// ```rust
554/// use structmeta::{Flag, StructMeta};
555/// use syn::{parse_quote, Attribute};
556///
557/// #[derive(StructMeta)]
558/// struct Args {
559/// a: Flag,
560/// }
561///
562/// let attr: Attribute = parse_quote!(#[attr(a)]);
563/// let args: Args = attr.parse_args()?;
564/// if let Some(_span) = args.a.span {
565/// // Use span.
566/// }
567/// # syn::Result::Ok(())
568/// ```
569///
570/// ## NameValue style
571///
572/// A field with type `T` or `NameValue<T>` will be `name = value` style parameter.
573///
574/// ```rust
575/// use structmeta::{NameValue, StructMeta};
576/// use syn::{parse_quote, Attribute, LitInt, LitStr};
577///
578/// #[derive(StructMeta)]
579/// struct Args {
580/// a: LitStr,
581/// b: NameValue<LitInt>,
582/// }
583///
584/// let attr: Attribute = parse_quote!(#[attr(a = "abc", b = 10)]);
585/// let args: Args = attr.parse_args()?;
586/// assert_eq!(args.a.value(), "abc");
587/// assert_eq!(args.b.value.base10_parse::<u32>()?, 10);
588/// # syn::Result::Ok(())
589/// ```
590///
591/// ## NameValue or Flag style
592///
593/// A field with type `NameArgs<Option<T>>` will be `name = value` or `name` style parameter.
594///
595/// ```rust
596/// use structmeta::{NameValue, StructMeta};
597/// use syn::{parse_quote, Attribute, LitInt, LitStr};
598///
599/// #[derive(StructMeta)]
600/// struct Args {
601/// a: NameValue<Option<LitStr>>,
602/// b: NameValue<Option<LitInt>>,
603/// }
604///
605/// let attr: Attribute = parse_quote!(#[attr(a, b = 10)]);
606/// let args: Args = attr.parse_args()?;
607/// assert!(args.a.value.is_none());
608/// assert_eq!(args.b.value.unwrap().base10_parse::<u32>()?, 10);
609/// # syn::Result::Ok(())
610/// ```
611///
612/// ## NameArgs style
613///
614/// A field with type `NameArgs<T>` will be `name(args)` style parameter.
615///
616/// ```rust
617/// use structmeta::{NameArgs, StructMeta};
618/// use syn::{parse_quote, Attribute, LitInt, LitStr};
619///
620/// #[derive(StructMeta)]
621/// struct Args {
622/// a: NameArgs<LitStr>,
623/// b: NameArgs<LitInt>,
624/// }
625///
626/// let attr: Attribute = parse_quote!(#[attr(a("abc"), b(10))]);
627/// let args: Args = attr.parse_args()?;
628/// assert_eq!(args.a.args.value(), "abc");
629/// assert_eq!(args.b.args.base10_parse::<u32>()?, 10);
630/// # syn::Result::Ok(())
631/// ```
632///
633/// ## NameArgs or Flag style
634///
635/// A field with type `NameArgs<Option<T>>` will be `name(args)` or `name` style parameter.
636///
637/// ```rust
638/// use structmeta::{NameArgs, StructMeta};
639/// use syn::{parse_quote, Attribute, LitInt, LitStr};
640///
641/// #[derive(StructMeta)]
642/// struct Args {
643/// a: NameArgs<Option<LitStr>>,
644/// b: NameArgs<Option<LitInt>>,
645/// }
646///
647/// let attr: Attribute = parse_quote!(#[attr(a, b(10))]);
648/// let args: Args = attr.parse_args()?;
649/// assert!(args.a.args.is_none());
650/// assert_eq!(args.b.args.unwrap().base10_parse::<u32>()?, 10);
651/// # syn::Result::Ok(())
652/// ```
653///
654/// ## NameArgList style
655///
656/// A field with type `NameArgs<Vec<T>>` will be `name(arg, arg, ...)` style parameter.
657///
658/// ```rust
659/// use structmeta::{NameArgs, StructMeta};
660/// use syn::{parse_quote, Attribute, LitStr};
661///
662/// #[derive(StructMeta)]
663/// struct Args {
664/// a: NameArgs<Vec<LitStr>>,
665/// }
666///
667/// let attr: Attribute = parse_quote!(#[attr(a())]);
668/// let args: Args = attr.parse_args()?;
669/// assert_eq!(args.a.args.len(), 0);
670///
671/// let attr: Attribute = parse_quote!(#[attr(a("x"))]);
672/// let args: Args = attr.parse_args()?;
673/// assert_eq!(args.a.args.len(), 1);
674///
675/// let attr: Attribute = parse_quote!(#[attr(a("x", "y"))]);
676/// let args: Args = attr.parse_args()?;
677/// assert_eq!(args.a.args.len(), 2);
678/// # syn::Result::Ok(())
679/// ```
680///
681/// ## NameArgList or Flag style
682///
683/// A field with type `NameArgs<Option<Vec<T>>>` will be `name(arg, arg, ...)` or `name` style parameter.
684///
685/// ```rust
686/// use structmeta::{NameArgs, StructMeta};
687/// use syn::{parse_quote, Attribute, LitStr};
688///
689/// #[derive(StructMeta)]
690/// struct Args {
691/// abc: NameArgs<Option<Vec<LitStr>>>,
692/// }
693///
694/// let attr: Attribute = parse_quote!(#[attr(abc)]);
695/// let args: Args = attr.parse_args()?;
696/// assert_eq!(args.abc.args.is_none(), true);
697///
698/// let attr: Attribute = parse_quote!(#[attr(abc())]);
699/// let args: Args = attr.parse_args()?;
700/// assert_eq!(args.abc.args.unwrap().len(), 0);
701///
702/// let attr: Attribute = parse_quote!(#[attr(abc("x"))]);
703/// let args: Args = attr.parse_args()?;
704/// assert_eq!(args.abc.args.unwrap().len(), 1);
705///
706/// let attr: Attribute = parse_quote!(#[attr(abc("x", "y"))]);
707/// let args: Args = attr.parse_args()?;
708/// assert_eq!(args.abc.args.unwrap().len(), 2);
709/// # syn::Result::Ok(())
710/// ```
711///
712/// ## Optional named parameter
713///
714/// If you use `Option` for the field type, it becomes an optional parameter.
715///
716/// ```rust
717/// use structmeta::{NameValue, StructMeta};
718/// use syn::{parse_quote, Attribute, LitInt, LitStr};
719///
720/// #[derive(StructMeta)]
721/// struct Args {
722/// a: Option<LitStr>,
723/// b: Option<NameValue<LitInt>>,
724/// }
725///
726/// let attr: Attribute = parse_quote!(#[attr(a = "abc")]);
727/// let args: Args = attr.parse_args()?;
728/// assert!(args.a.is_some());
729/// assert!(args.b.is_none());
730///
731/// let attr: Attribute = parse_quote!(#[attr(b = 10)]);
732/// let args: Args = attr.parse_args()?;
733/// assert!(args.a.is_none());
734/// assert!(args.b.is_some());
735/// # syn::Result::Ok(())
736/// ```
737///
738/// ## Rest named parameter
739///
740/// If `HashMap<String, _>` is used for the field type, the field will contain named arguments that are not associated with the field.
741///
742/// ```rust
743/// use std::collections::HashMap;
744/// use structmeta::StructMeta;
745/// use syn::{parse_quote, Attribute, LitInt};
746///
747/// #[derive(StructMeta)]
748/// struct Args {
749/// a: Option<LitInt>,
750/// rest: HashMap<String, LitInt>,
751/// }
752///
753/// let attr: Attribute = parse_quote!(#[attr(a = 10, b = 20, c = 30)]);
754/// let args: Args = attr.parse_args()?;
755/// assert!(args.a.is_some());
756/// let mut keys: Vec<_> = args.rest.keys().collect();
757/// keys.sort();
758/// assert_eq!(keys, vec!["b", "c"]);
759/// # syn::Result::Ok(())
760/// ```
761///
762/// # Unnamed parameter
763///
764/// The following field will be "Unnamed parameter".
765///
766/// - field in tuple struct.
767/// - field with `#[struct_meta(unnamed)]` in record struct.
768/// - However, fields that meet the following conditions are excluded
769/// - field with `#[struct_meta(name = "...")]`
770/// - field with type `HashMap<String, _>`
771///
772/// "Unnamed parameter" is a value-only parameter, such as `#[attr("abc", 10, 20)]`.
773///
774/// | field type | effect |
775/// | ----------- | ------------------------------------------------- |
776/// | `T` | [required parameter](#required-unnamed-parameter) |
777/// | `Option<T>` | [optional parameter](#optional-unnamed-parameter) |
778/// | `Vec<T>` | [variadic parameter](#variadic-unnamed-parameter) |
779///
780/// The type `T` in the table above needs to implement `syn::parse::Parse`.
781///
782/// ## Required unnamed parameter
783///
784/// Fields of the type that implement `syn::parse::Parse` will be required parameters.
785///
786/// ```rust
787/// use structmeta::StructMeta;
788/// use syn::{parse_quote, Attribute, LitStr, Result};
789///
790/// #[derive(StructMeta)]
791/// struct Args(LitStr);
792///
793/// let attr: Attribute = parse_quote!(#[attr()]);
794/// let args: Result<Args> = attr.parse_args();
795/// assert!(args.is_err());
796///
797/// let attr: Attribute = parse_quote!(#[attr("a")]);
798/// let args: Args = attr.parse_args()?;
799/// assert_eq!(args.0.value(), "a");
800/// # syn::Result::Ok(())
801/// ```
802///
803/// ## Optional unnamed parameter
804///
805/// Fields of type `Option` will be optional parameters.
806///
807/// ```rust
808/// use structmeta::StructMeta;
809/// use syn::{parse_quote, Attribute, LitStr};
810///
811/// #[derive(StructMeta)]
812/// struct Args(Option<LitStr>);
813///
814/// let attr: Attribute = parse_quote!(#[attr()]);
815/// let args: Args = attr.parse_args()?;
816/// assert!(args.0.is_none());
817///
818/// let attr: Attribute = parse_quote!(#[attr("a")]);
819/// let args: Args = attr.parse_args()?;
820/// assert_eq!(args.0.unwrap().value(), "a");
821/// # syn::Result::Ok(())
822/// ```
823///
824/// ## Variadic unnamed parameter
825///
826/// If you use `Vec` as the field type, multiple arguments can be stored in a single field.
827///
828/// ```rust
829/// use structmeta::StructMeta;
830/// use syn::{parse_quote, Attribute, LitStr};
831///
832/// #[derive(StructMeta)]
833/// struct Args(Vec<LitStr>);
834///
835/// let attr: Attribute = parse_quote!(#[attr()]);
836/// let args: Args = attr.parse_args()?;
837/// assert_eq!(args.0.len(), 0);
838///
839/// let attr: Attribute = parse_quote!(#[attr("a")]);
840/// let args: Args = attr.parse_args()?;
841/// assert_eq!(args.0.len(), 1);
842/// assert_eq!(args.0[0].value(), "a");
843///
844/// let attr: Attribute = parse_quote!(#[attr("a", "b")]);
845/// let args: Args = attr.parse_args()?;
846/// assert_eq!(args.0.len(), 2);
847/// assert_eq!(args.0[0].value(), "a");
848/// assert_eq!(args.0[1].value(), "b");
849/// # syn::Result::Ok(())
850/// ```
851///
852/// # Parameter order
853///
854/// The parameters must be in the following order.
855///
856/// - Unnamed
857/// - Required
858/// - Optional
859/// - Variadic
860/// - Named
861///
862/// # Helper attribute `#[struct_meta(...)]`
863///
864/// | argument | struct | field | effect |
865/// | -------------------------------------------------- | ------ | ----- | ---------------------------------------------------------------------------------------- |
866/// | `dump` | ✔ | | Causes a compile error and outputs the automatically generated code as an error message. |
867/// | [`name_filter = "..."`](#struct_metaname_filter--) | ✔ | | Specify how to distinguish between a parameter name and a value of an unnamed parameter. |
868/// | `name = "..."` | | ✔ | Specify a parameter name. |
869/// | `unnamed` | | ✔ | Make the field be treated as an unnamed parameter. |
870///
871/// # Uses with `#[proc_macro_derive]`
872///
873/// A type with `#[derive(StructMeta)]` can be used with [`syn::Attribute::parse_args`].
874///
875/// ```rust
876/// # extern crate proc_macro;
877/// use proc_macro::TokenStream;
878/// use quote::quote;
879/// use structmeta::StructMeta;
880/// use syn::{parse, parse_macro_input, DeriveInput, LitStr};
881///
882/// #[derive(StructMeta)]
883/// struct MyAttr {
884/// msg: LitStr,
885/// }
886///
887/// # const IGNORE_TOKENS: &str = stringify! {
888/// #[proc_macro_derive(MyMsg, attributes(my_msg))]
889/// # };
890/// pub fn derive_my_msg(input: TokenStream) -> TokenStream {
891/// let input = parse_macro_input!(input as DeriveInput);
892/// let mut msg = String::new();
893/// for attr in input.attrs {
894/// if attr.path().is_ident("my_msg") {
895/// let attr = attr.parse_args::<MyAttr>().unwrap();
896/// msg = attr.msg.value();
897/// }
898/// }
899/// quote!(const MSG: &str = #msg;).into()
900/// }
901/// ```
902///
903/// ```ignore
904/// #[derive(MyMsg)]
905/// #[my_msg(msg = "abc")]
906/// struct TestType;
907///
908/// assert_eq!(MSG, "abc");
909/// ```
910///
911/// # Uses with `#[proc_macro_attribute]`
912///
913/// A type with `#[derive(StructMeta)]` can be used with `attr` parameter in attribute proc macro.
914///
915/// ```rust
916/// # extern crate proc_macro;
917/// use proc_macro::TokenStream;
918/// use quote::quote;
919/// use structmeta::StructMeta;
920/// use syn::{parse, parse_macro_input, DeriveInput, LitStr};
921///
922/// #[derive(StructMeta)]
923/// struct MyAttr {
924/// msg: LitStr,
925/// }
926/// # const IGNORE_TOKENS: &str = stringify! {
927/// #[proc_macro_attribute]
928/// # };
929/// pub fn my_attr(attr: TokenStream, _item: TokenStream) -> TokenStream {
930/// let attr = parse::<MyAttr>(attr).unwrap();
931/// let msg = attr.msg.value();
932/// quote!(const MSG: &str = #msg;).into()
933/// }
934/// ```
935///
936/// ```ignore
937/// #[my_attr(msg = "xyz")]
938/// struct TestType;
939///
940/// assert_eq!(MSG, "xyz");
941/// ```
942///
943/// # Parsing ambiguous arguments
944///
945/// If one or more `name = value` style parameters are defined, arguments beginning with `name =` will be parsed as `name = value` style,
946/// even if the name is different from what it is defined as.
947///
948/// This specification is intended to prevent `name = value` from being treated as unnamed parameter due to typo.
949///
950/// ```rust
951/// use structmeta::StructMeta;
952/// use syn::{parse_quote, Attribute, Expr, LitInt, Result};
953///
954/// #[derive(StructMeta)]
955/// struct WithNamed {
956/// #[struct_meta(unnamed)]
957/// unnamed: Option<Expr>,
958/// x: Option<LitInt>,
959/// }
960///
961/// let attr_x: Attribute = parse_quote!(#[attr(x = 10)]);
962/// let result: WithNamed = attr_x.parse_args().unwrap();
963/// assert_eq!(result.unnamed.is_some(), false);
964/// assert_eq!(result.x.is_some(), true);
965///
966/// // `y = 10` is parsed as a wrong named parameter.
967/// let attr_y: Attribute = parse_quote!(#[attr(y = 10)]);
968/// let result: Result<WithNamed> = attr_y.parse_args();
969/// assert!(result.is_err());
970/// ```
971///
972/// If `name = value` style parameter is not defined, it will be parsed as unnamed parameter.
973///
974/// ```rust
975/// use structmeta::StructMeta;
976/// use syn::{parse_quote, Attribute, Expr, LitInt, Result};
977///
978/// #[derive(StructMeta)]
979/// struct WithoutNamed {
980/// #[struct_meta(unnamed)]
981/// unnamed: Option<Expr>,
982/// }
983///
984/// // `y = 10` is parsed as a unnamed parameter.
985/// let attr_y: Attribute = parse_quote!(#[attr(y = 10)]);
986/// let result: WithoutNamed = attr_y.parse_args().unwrap();
987/// assert_eq!(result.unnamed, Some(parse_quote!(y = 10)));
988/// ```
989///
990/// Similarly, if one or more `name(args)` style parameters are defined, arguments with `name(args)` will be parsed as `name(args)` style.
991/// If `name(args)` style parameter is not defined, it will be parsed as unnamed parameter.
992///
993/// The same is true for `name` or `name = value` style parameter.
994///
995/// ## `#[struct_meta(name_filter = "...")]`
996///
997/// 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.
998///
999/// The following value can be used.
1000///
1001/// - `"snake_case"`
1002///
1003/// ```rust
1004/// use structmeta::StructMeta;
1005/// use syn::{parse_quote, Attribute, Expr, LitInt, Result};
1006///
1007/// let attr_x: Attribute = parse_quote!(#[attr(X)]);
1008/// let attr_y: Attribute = parse_quote!(#[attr(Y)]);
1009///
1010/// #[derive(StructMeta)]
1011/// struct NoFilter {
1012/// #[struct_meta(unnamed)]
1013/// unnamed: Option<Expr>,
1014/// #[struct_meta(name = "X")]
1015/// x: bool,
1016/// }
1017/// let result: NoFilter = attr_x.parse_args().unwrap();
1018/// assert_eq!(result.unnamed, None);
1019/// assert_eq!(result.x, true); // `X` is parsed as a named parameter.
1020///
1021/// let result: Result<NoFilter> = attr_y.parse_args();
1022/// assert!(result.is_err()); // `Y` is parsed as a wrong named parameter.
1023///
1024///
1025/// #[derive(StructMeta)]
1026/// #[struct_meta(name_filter = "snake_case")]
1027/// struct WithFilter {
1028/// #[struct_meta(unnamed)]
1029/// unnamed: Option<Expr>,
1030/// #[struct_meta(name = "X")]
1031/// x: bool,
1032/// }
1033/// let result: WithFilter = attr_x.parse_args().unwrap();
1034/// assert_eq!(result.unnamed, Some(parse_quote!(X))); // `X` is parsed as a unnamed parameter.
1035/// assert_eq!(result.x, false);
1036/// ```
1037// #[include_doc("../../doc/struct_meta.md", end)]
1038pub use structmeta_derive::StructMeta;