from_attr/parse_meta.rs
1use proc_macro2::TokenStream;
2use syn::{
3 meta::{self, ParseNestedMeta},
4 parse::Parser,
5 Attribute, Meta, MetaList,
6};
7
8/// Used to enable parsing of each [`meta`](syn::meta::ParseNestedMeta).
9///
10/// Generally an helper struct is generated from the derive macro [`FromAttr`](macro@crate::FromAttr),
11/// and an implementation of the [`ParseMeta`] trait is generated on this struct.
12pub trait ParseMeta {
13 /// Whether the type is unit type.
14 fn is_unit() -> bool;
15
16 /// Parse one [`meta`](syn::meta::ParseNestedMeta).
17 fn parse_meta(&mut self, meta: ParseNestedMeta) -> syn::Result<()>;
18
19 /// Parse one [`Attribute`].
20 fn parse_attr(&mut self, attr: &Attribute) -> syn::Result<()> {
21 if Self::is_unit() {
22 attr.meta.require_path_only().map(|_| ())
23 } else if matches!(attr.meta, Meta::Path(_)) {
24 // #[one(a, b, c)]
25 // if `a`, `b`, `c` all have default value,
26 // it should be allowed to be written as `#[one]`
27 // instead of having to be written as `#[one()]`
28 Ok(())
29 } else {
30 attr.parse_nested_meta(|meta| self.parse_meta(meta))
31 }
32 }
33
34 /// Parse one [`MetaList`].
35 fn parse_meta_list(&mut self, meta_list: &MetaList) -> syn::Result<()> {
36 meta_list.parse_nested_meta(|meta| self.parse_meta(meta))
37 }
38
39 /// Parse one [`TokenStream`].
40 fn parse_tokens(&mut self, tokens: TokenStream) -> syn::Result<()> {
41 meta::parser(|meta| self.parse_meta(meta)).parse2(tokens)
42 }
43}