codama_syn_helpers/extensions/
attribute.rs1use super::PathExtension;
2use syn::{punctuated::Punctuated, Attribute};
3
4pub trait AttributeExtension {
5 fn get_self(&self) -> &Attribute;
6
7 fn parse_comma_args<T: syn::parse::Parse>(&self) -> syn::Result<Vec<T>> {
9 self.get_self()
10 .parse_args_with(Punctuated::<T, syn::Token![,]>::parse_terminated)
11 .map(|metas| metas.into_iter().collect::<Vec<_>>())
12 }
13
14 fn unfeatured(&self) -> Option<Attribute> {
18 let this = self.get_self();
19 if !this.path().is_strict("cfg_attr") {
20 return None;
21 }
22 let metas = this.parse_comma_args::<syn::Meta>().ok()?;
23 let [feature, inner_meta] = metas.as_slice() else {
24 return None;
25 };
26 match feature {
27 syn::Meta::NameValue(m) if m.path.is_strict("feature") => (),
28 _ => return None,
29 }
30 Some(Attribute {
31 pound_token: this.pound_token,
32 style: this.style,
33 bracket_token: this.bracket_token,
34 meta: inner_meta.clone(),
35 })
36 }
37}
38
39impl AttributeExtension for Attribute {
40 fn get_self(&self) -> &Attribute {
41 self
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use quote::{quote, ToTokens};
49 use syn::parse_quote;
50
51 #[test]
52 fn parse_comma_args_ok() {
53 let attribute: Attribute = parse_quote! { #[foo(42, "bar")] };
54 let args = attribute.parse_comma_args::<syn::Lit>().unwrap();
55 assert_eq!(args.len(), 2);
56 }
57
58 #[test]
59 fn parse_comma_args_err() {
60 let attribute: Attribute = parse_quote! { #[foo] };
61 let args = attribute.parse_comma_args::<syn::Path>();
62 assert!(args.is_err());
63 }
64
65 #[test]
66 fn unfeatured() {
67 let attribute: Attribute =
68 parse_quote! { #[cfg_attr(feature = "some_feature", derive(Debug))] };
69 let unfeatured = attribute.unfeatured();
70 assert_eq!(
71 unfeatured.to_token_stream().to_string(),
72 quote! { #[derive(Debug)] }.to_string()
73 );
74 }
75
76 #[test]
77 fn unfeatured_unchanged() {
78 let attribute: Attribute = parse_quote! { #[derive(Debug)] };
79 let unfeatured = attribute.unfeatured();
80 assert_eq!(unfeatured, None);
81 }
82}