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}