use syn::DeriveInput; use crate::symbol::Symbol; pub fn parse_attrs(ast: &DeriveInput, attr_name: Symbol) -> syn::Result> { let mut list = Vec::new(); for attr in ast.attrs.iter().filter(|a| a.path == attr_name) { match attr.parse_meta()? { syn::Meta::List(meta) => list.extend(meta.nested.into_iter()), other => { return Err(syn::Error::new_spanned( other, format!("expected #[{attr_name}(...)]"), )) } } } Ok(list) } pub fn get_lit_str(attr_name: Symbol, lit: &syn::Lit) -> syn::Result<&syn::LitStr> { if let syn::Lit::Str(lit) = lit { Ok(lit) } else { Err(syn::Error::new_spanned( lit, format!( "expected {} attribute to be a string: `{} = \"...\"`", attr_name, attr_name ), )) } } pub fn get_lit_bool(attr_name: Symbol, lit: &syn::Lit) -> syn::Result { if let syn::Lit::Bool(lit) = lit { Ok(lit.value()) } else { Err(syn::Error::new_spanned( lit, format!( "expected {} attribute to be a bool value, `true` or `false`: `{} = ...`", attr_name, attr_name ), )) } }