cido-macros 0.2.0

Macros for generating code that enables easier interfacing with cido
Documentation
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()
  }
}