use proc_macro::TokenStream;
use quote::quote;
use syn::Token;
use syn::parse::Parser;
use syn::punctuated::Punctuated;
pub(crate) fn united_error(attr: TokenStream, item: TokenStream) -> TokenStream {
let attr_ts = proc_macro2::TokenStream::from(attr);
let item_ts = proc_macro2::TokenStream::from(item);
let item_ast = match syn::parse2::<syn::ItemStruct>(item_ts.clone()) {
Ok(s) => s,
Err(e) => return e.to_compile_error().into(),
};
let ident = &item_ast.ident;
let vis = &item_ast.vis;
let members = match parse_members(&attr_ts) {
Ok(m) => m,
Err(e) => return e.to_compile_error().into(),
};
let members_attr = quote! {
#[::struct_error::__struct_error_members(#(#members),*)]
};
let expanded = quote! {
#[::macro_magic::export_tokens]
#members_attr
#vis struct #ident;
};
expanded.into()
}
fn parse_members(attr_ts: &proc_macro2::TokenStream) -> syn::Result<Vec<syn::Path>> {
let paths = Punctuated::<syn::Path, Token![,]>::parse_terminated.parse2(attr_ts.clone())?;
Ok(paths.into_iter().collect())
}