pub(crate) fn extract_deprecation(attrs: &[syn::Attribute]) -> Option<crate::core::ir::DeprecationInfo> {
attrs.iter().find_map(|attr| {
if !attr.path().is_ident("deprecated") {
return None;
}
let mut info = crate::core::ir::DeprecationInfo::default();
let _ = attr.parse_nested_meta(|meta| {
if meta.path.is_ident("since") {
if let Ok(v) = meta.value()
&& let Ok(s) = v.parse::<syn::LitStr>()
{
let raw = s.value();
info.since = Some(raw.strip_prefix('v').map(str::to_owned).unwrap_or(raw));
}
} else if meta.path.is_ident("note") {
if let Ok(v) = meta.value()
&& let Ok(s) = v.parse::<syn::LitStr>()
{
info.note = Some(s.value());
}
} else if let Ok(v) = meta.value() {
let _: syn::Expr = v.parse()?;
}
Ok(())
});
Some(info)
})
}
pub(crate) fn extract_alef_since(attrs: &[syn::Attribute]) -> Option<String> {
let raw = attrs.iter().find_map(|attr| {
if attr.path().is_ident("alef") {
let mut found = None;
let _ = attr.parse_nested_meta(|meta| {
if meta.path.is_ident("since") {
if let Ok(v) = meta.value()
&& let Ok(s) = v.parse::<syn::LitStr>()
{
found = Some(s.value());
}
} else if let Ok(v) = meta.value() {
let _: syn::Expr = v.parse()?;
}
Ok(())
});
return found;
}
if attr.path().is_ident("cfg_attr") {
let mut found = None;
let _ = attr.parse_nested_meta(|meta| {
if meta.path.is_ident("alef") {
let _ = meta.parse_nested_meta(|inner| {
if inner.path.is_ident("since") {
if let Ok(v) = inner.value()
&& let Ok(s) = v.parse::<syn::LitStr>()
{
found = Some(s.value());
}
} else if let Ok(v) = inner.value() {
let _: syn::Expr = v.parse()?;
}
Ok(())
});
} else if let Ok(v) = meta.value() {
let _: syn::Expr = v.parse()?;
} else {
let _ = meta.parse_nested_meta(|_| Ok(()));
}
Ok(())
});
return found;
}
None
})?;
Some(raw.strip_prefix('v').map(str::to_owned).unwrap_or(raw))
}
pub(crate) fn extract_version_annotation(attrs: &[syn::Attribute]) -> crate::core::ir::VersionAnnotation {
crate::core::ir::VersionAnnotation {
legacy_constructor_fields: Vec::new(),
since: extract_alef_since(attrs),
deprecated: extract_deprecation(attrs),
}
}