diff options
Diffstat (limited to 'mingling_macros/src/extensions')
| -rw-r--r-- | mingling_macros/src/extensions/routeify.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/mingling_macros/src/extensions/routeify.rs b/mingling_macros/src/extensions/routeify.rs new file mode 100644 index 0000000..f011fb9 --- /dev/null +++ b/mingling_macros/src/extensions/routeify.rs @@ -0,0 +1,39 @@ +//! The `#[routeify]` extension — transforms `expr?` into `route!(expr)`. +//! +//! Designed as an extension for the Mingling attribute macro system, intended +//! to be used with `#[chain(routeify)]` or standalone as `#[routeify]`. +//! +//! # How it works +//! +//! The macro parses the function AST and replaces every `Expr::Try` node with an +//! equivalent `route!(expr)` invocation. + +use proc_macro::TokenStream; +use quote::ToTokens; +use syn::visit_mut::VisitMut; +use syn::{Expr, ItemFn, parse_macro_input}; + +struct RouteifyTransform; + +impl VisitMut for RouteifyTransform { + fn visit_expr_mut(&mut self, expr: &mut Expr) { + syn::visit_mut::visit_expr_mut(self, expr); + + if let Expr::Try(try_expr) = expr { + let inner = &*try_expr.expr; + let inner_tokens = inner.to_token_stream(); + + if let Ok(macro_expr) = syn::parse2::<Expr>(quote::quote! { + ::mingling::macros::route!(#inner_tokens) + }) { + *expr = macro_expr; + } + } + } +} + +pub(crate) fn routeify_impl(_attr: TokenStream, item: TokenStream) -> TokenStream { + let mut input_fn = parse_macro_input!(item as ItemFn); + RouteifyTransform.visit_item_fn_mut(&mut input_fn); + input_fn.to_token_stream().into() +} |
