cvlr_early_panic/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::visit_mut::{self, VisitMut};
4use syn::{parse_macro_input, parse_quote, Expr, ItemFn};
5
6/// Replaces question mark operator by unwrap
7struct EarlyPanic;
8
9impl VisitMut for EarlyPanic {
10    fn visit_expr_mut(&mut self, node: &mut Expr) {
11        if let Expr::Try(expr) = &mut *node {
12            let prefix: &mut Expr = expr.expr.as_mut();
13            // -- recurse on prefix since it might have nested q-mark
14            visit_mut::visit_expr_mut(self, prefix);
15            *node = parse_quote!(#prefix.unwrap());
16            return;
17        }
18
19        // -- recurse on other expression types
20        visit_mut::visit_expr_mut(self, node);
21    }
22}
23
24/// Attribute to replace question mark operator by unwrap.
25///
26/// # Example
27///
28/// ```
29/// use cvlr_early_panic::early_panic;
30/// #[early_panic]
31/// fn foo() -> Option<u64> {
32///     let v = "42".parse::<u64>()?;
33///     Some(v)
34/// }
35/// ```
36#[proc_macro_attribute]
37pub fn early_panic(_args: TokenStream, input: TokenStream) -> TokenStream {
38    let mut fn_ast = parse_macro_input!(input as ItemFn);
39    EarlyPanic.visit_item_fn_mut(&mut fn_ast);
40    TokenStream::from(quote!(#fn_ast))
41}
OSZAR »