use darling::FromMeta;
use getset::Getters;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_quote_spanned, spanned::Spanned, Meta};
#[derive(Debug, Clone, Getters)]
#[getset(get = "pub")]
pub struct FXAttributes {
list: Vec<syn::Attribute>,
}
impl FromMeta for FXAttributes {
fn from_meta(input: &Meta) -> Result<Self, darling::Error> {
match input {
Meta::List(ref ml) => {
let ml_chunks: Vec<TokenStream> = vec![TokenStream::new()];
let mut ml_chunks = ml.tokens.clone().into_iter().fold(ml_chunks, |mut mlc, item| {
if let proc_macro2::TokenTree::Punct(_) = item {
mlc.push(TokenStream::new());
}
else {
mlc.last_mut().unwrap().extend([item]);
}
mlc
});
if let Some(last_meta) = ml_chunks.last() {
if last_meta.is_empty() {
let _ = ml_chunks.pop();
}
}
let pound = quote![#];
Ok(Self {
list: ml_chunks
.iter()
.map(|tt| parse_quote_spanned!(tt.span()=> #pound [ #tt ]))
.collect(),
})
}
_ => unimplemented!("Can't deal with this kind of input"),
}
}
}
impl ToTokens for FXAttributes {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(self.list.iter().map(|a| a.to_token_stream()));
}
}