From ec9c540839730be08dbb150b1ef49973e071b19c Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi Date: Thu, 23 Jul 2020 23:56:25 +0600 Subject: [PATCH] Add #[handler], #[bot_dialogue] --- Cargo.toml | 2 +- src/lib.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 557f7802..b9af08b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] quote = "1.0.3" -syn = "1.0.13" +syn = { version = "1.0.13", features = ["full"] } [lib] proc-macro = true diff --git a/src/lib.rs b/src/lib.rs index 1e9c9d51..9c26f972 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +// TODO: refactor this shit. + mod attr; mod command; mod command_enum; @@ -15,7 +17,46 @@ use crate::{ }; use proc_macro::TokenStream; use quote::{quote, ToTokens}; -use syn::{parse_macro_input, DeriveInput, Fields}; +use syn::{parse_macro_input, DeriveInput, Fields, ItemEnum}; + +use std::fmt::Write; + +#[proc_macro_attribute] +pub fn handler(_attr: TokenStream, item: TokenStream) -> TokenStream { + item +} + +#[proc_macro_attribute] +pub fn bot_dialogue(_attr: TokenStream, item: TokenStream) -> TokenStream { + let input = parse_macro_input!(item as ItemEnum); + let mut dispatch_fn = "".to_owned(); + + write!(dispatch_fn, "impl {0} {{ pub fn dispatch(self, cx: teloxide::dispatching::UpdateWithCx) -> TransitionOut<{0}> {{ match self {{", input.ident).unwrap(); + + for variant in input.variants.iter() { + if let Some(handler) = variant + .attrs + .iter() + .find(|attr| match attr.path.get_ident() { + Some(ident) => ident == "handler", + None => false, + }) + { + let mut handler_fn = handler.tokens.to_string()[1..].to_owned(); + handler_fn.pop(); + + write!( + dispatch_fn, + "{}::{}(state) => {}(cx, state).await,", + input.ident, variant.ident, handler_fn + ) + .unwrap(); + } + } + + write!(dispatch_fn, "}} }} }}").unwrap(); + dispatch_fn.parse().unwrap() +} macro_rules! get_or_return { ($($some:tt)*) => {