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;