#![doc = include_str!("../README.md")]
mod block_logic;
mod macro_gen;
mod permute;
mod traits;
use proc_macro as pm;
use proc_macro2 as pm2;
use syn::spanned::Spanned;
pub(crate) const ROOT_VISIBILITY_IDENT: &str = "crate";
pub(crate) const DEFAULT_HELPER_ATTR: &str = "def";
macro_rules! syn_parses {
($item: expr, $($id: path),+) => {
(
concat!($(concat!(stringify!($id), ", ")),+),
($(syn::parse::<$id>($item.clone())),+)
)
}
}
#[proc_macro_attribute]
pub fn defamed(attrs: pm::TokenStream, input: pm::TokenStream) -> pm::TokenStream {
let item_path = match attrs.is_empty() {
true => None,
false => {
let ex: syn::Expr = syn::parse_macro_input!(attrs);
if let syn::Expr::Path(syn::ExprPath { path, .. }) = &ex {
Some(path.clone())
} else {
return syn::Error::new(ex.span(), "Expected path expression")
.to_compile_error()
.into();
}
}
};
let (expected_str, parsed) = syn_parses!(input, syn::ItemStruct, syn::ItemFn);
let res = match parsed {
(Ok(s), _) => block_logic::item_struct(s, item_path),
(_, Ok(f)) => block_logic::item_fn(f, item_path),
_ => syn::Error::new(
pm2::Span::call_site(),
format!("Item not supported. Expected: {}", expected_str),
)
.to_compile_error()
.into(),
};
res.into()
}