use deluxe::ParseMetaItem;
use syn::Attribute;
use super::debug::Dbg;
#[derive(Clone, Debug, Default)]
pub struct Attributes(Vec<Dbg<syn::Meta>>);
impl ParseMetaItem for Attributes {
fn parse_meta_item(
input: syn::parse::ParseStream,
mode: deluxe::ParseMode,
) -> deluxe::Result<Self> {
if let Ok(vec) = Vec::<syn::Meta>::parse_meta_item(input, mode) {
return Ok(Self(vec.into_iter().map(Dbg).collect()));
}
if let Ok(s) = syn::Meta::parse_meta_item(input, mode) {
return Ok(Self(vec![Dbg(s)]));
}
if let Ok(a) = syn::Attribute::parse_outer(input) {
return Ok(Self(a.into_iter().map(|a| Dbg(a.meta)).collect()));
}
Err(crate::parse::err_span(
input.span(),
"Unable to parse Attributes",
))
}
}
impl TryFrom<proc_macro2::TokenStream> for Attributes {
type Error = syn::Error;
fn try_from(value: proc_macro2::TokenStream) -> Result<Self, Self::Error> {
use syn::parse::Parser;
let f = |t: syn::parse::ParseStream| -> syn::Result<Attributes> {
Self::parse_meta_item(t, deluxe::ParseMode::Unnamed)
};
f.parse2(value)
}
}
impl From<Vec<Attribute>> for Attributes {
fn from(value: Vec<Attribute>) -> Self {
Self(value.into_iter().map(|a| Dbg(a.meta)).collect())
}
}
impl Attributes {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn outer_attributes(&self) -> Vec<Attribute> {
self
.0
.iter()
.map(|m| syn::Attribute {
pound_token: Default::default(),
style: syn::AttrStyle::Outer,
bracket_token: Default::default(),
meta: m.0.clone(),
})
.collect()
}
}