ral_macro/
parse.rs

1use std::collections::HashMap;
2
3use proc_macro2::{Ident, Span};
4use syn::spanned::Spanned;
5use syn::{Attribute, Lit, LitStr, Meta, Result};
6
7pub(super) fn adjust_ident(ident: Ident) -> Ident {
8    let string_ident = ident.to_string();
9    if string_ident.starts_with("_") {
10        Ident::new(string_ident.trim_start_matches("_"), ident.span())
11    } else {
12        ident
13    }
14}
15
16pub(super) fn attrs_to_meta_map(attrs: Vec<Attribute>) -> Result<HashMap<String, Meta>> {
17    let attrs_iter = attrs
18        .iter()
19        .map(Attribute::parse_meta)
20        .filter_map(Result::<Meta>::ok);
21    let mut attrs = HashMap::new();
22    for attr in attrs_iter {
23        let name = attr
24            .path()
25            .get_ident()
26            .ok_or(syn::Error::new(
27                attr.path().span(),
28                "attribute path is not identifier",
29            ))?
30            .to_string();
31        attrs.insert(name, attr);
32    }
33    Ok(attrs)
34}
35
36pub(super) fn get_meta(
37    attr_name: &str,
38    attrs: &mut HashMap<String, Meta>,
39    span: Span,
40) -> Result<LitStr> {
41    attrs
42        .remove(attr_name)
43        .and_then(|meta| {
44            if let Meta::NameValue(attr) = meta {
45                Some(attr.lit)
46            } else {
47                None
48            }
49        })
50        .and_then(|lit| {
51            if let Lit::Str(value) = lit {
52                Some(value)
53            } else {
54                None
55            }
56        })
57        .ok_or(syn::Error::new(
58            span,
59            format!("{} attribute is not specified", attr_name),
60        ))
61}