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}