linkme_impl/
attr.rs

1use syn::parse::{Error, Result};
2use syn::{parse_quote, Attribute, Path};
3
4// #[linkme(crate = path::to::linkme)]
5pub(crate) fn linkme_path(attrs: &mut Vec<Attribute>) -> Result<Path> {
6    let mut linkme_path = None;
7    let mut errors: Option<Error> = None;
8
9    attrs.retain(|attr| {
10        if !attr.path().is_ident("linkme") {
11            return true;
12        }
13        if let Err(err) = attr.parse_nested_meta(|meta| {
14            if meta.path.is_ident("crate") {
15                if linkme_path.is_some() {
16                    return Err(meta.error("duplicate linkme crate attribute"));
17                }
18                let path = meta.value()?.call(Path::parse_mod_style)?;
19                linkme_path = Some(path);
20                Ok(())
21            } else {
22                Err(meta.error("unsupported linkme attribute"))
23            }
24        }) {
25            match &mut errors {
26                None => errors = Some(err),
27                Some(errors) => errors.combine(err),
28            }
29        }
30        false
31    });
32
33    match errors {
34        None => Ok(linkme_path.unwrap_or_else(|| parse_quote!(::linkme))),
35        Some(errors) => Err(errors),
36    }
37}