summaryrefslogtreecommitdiff
path: root/src/attr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/attr.rs')
-rw-r--r--src/attr.rs37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/attr.rs b/src/attr.rs
new file mode 100644
index 0000000..dca1511
--- /dev/null
+++ b/src/attr.rs
@@ -0,0 +1,37 @@
+use syn::parse::{Error, Result};
+use syn::{parse_quote, Attribute, Path};
+
+// #[linkme(crate = path::to::linkme)]
+pub(crate) fn linkme_path(attrs: &mut Vec<Attribute>) -> Result<Path> {
+ let mut linkme_path = None;
+ let mut errors: Option<Error> = None;
+
+ attrs.retain(|attr| {
+ if !attr.path().is_ident("linkme") {
+ return true;
+ }
+ if let Err(err) = attr.parse_nested_meta(|meta| {
+ if meta.path.is_ident("crate") {
+ if linkme_path.is_some() {
+ return Err(meta.error("duplicate linkme crate attribute"));
+ }
+ let path = meta.value()?.call(Path::parse_mod_style)?;
+ linkme_path = Some(path);
+ Ok(())
+ } else {
+ Err(meta.error("unsupported linkme attribute"))
+ }
+ }) {
+ match &mut errors {
+ None => errors = Some(err),
+ Some(errors) => errors.combine(err),
+ }
+ }
+ false
+ });
+
+ match errors {
+ None => Ok(linkme_path.unwrap_or_else(|| parse_quote!(::linkme))),
+ Some(errors) => Err(errors),
+ }
+}