use proc_macro::TokenStream;
use quote::{quote, quote_spanned};
use syn::spanned::Spanned;
use syn::{parse_macro_input, visit_mut::VisitMut, Expr};
#[proc_macro_attribute]
pub fn wherr(_attrs: TokenStream, input: TokenStream) -> TokenStream {
let mut function = parse_macro_input!(input as syn::ItemFn);
let mut visitor = WherrVisitor;
visitor.visit_item_fn_mut(&mut function);
TokenStream::from(quote! { #function })
}
struct WherrVisitor;
impl VisitMut for WherrVisitor {
fn visit_expr_mut(&mut self, expr: &mut Expr) {
if let Expr::Try(expr_try) = expr {
let span = expr_try.question_token.span();
let inner_expr = &expr_try.expr;
let new_expr = syn::parse2(quote_spanned! { span=>
wherr::wherrapper(#inner_expr, file!(), line!())?
})
.expect("Failed to create wherr wrapped expression");
*expr = new_expr;
} else {
syn::visit_mut::visit_expr_mut(self, expr);
}
}
}