From 845cd453d65b3b62a694fef5ca16240b8f7d118e Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 22 Aug 2022 15:21:20 +0400 Subject: [PATCH] Remove `derive(DialogueState)` macro It was already deprecated and it doesn't seem valuable to keep/refactor it. --- src/dialogue_state.rs | 229 ------------------------------------------ src/lib.rs | 13 +-- 2 files changed, 1 insertion(+), 241 deletions(-) delete mode 100644 src/dialogue_state.rs diff --git a/src/dialogue_state.rs b/src/dialogue_state.rs deleted file mode 100644 index ebb96ad7..00000000 --- a/src/dialogue_state.rs +++ /dev/null @@ -1,229 +0,0 @@ -use proc_macro2::{Ident, Span, TokenStream}; -use quote::{format_ident, quote, ToTokens}; -use syn::{ - parse::{Parse, ParseStream}, - spanned::Spanned, - Fields, FieldsNamed, GenericParam, ItemEnum, Path, Type, -}; - -pub fn expand(item: ItemEnum) -> Result { - let enum_ident = &item.ident; - let self_params_with_bounds = { - let params = &item.generics.params; - if !params.is_empty() { - quote! { < #params > } - } else { - quote! {} - } - }; - let self_params = { - let params = &item.generics.params; - if !params.is_empty() { - let mut params = quote! { < }; - item.generics.params.iter().for_each(|param| match param { - GenericParam::Type(ty) => { - let ident = &ty.ident; - params.extend(quote! { #ident, }); - } - GenericParam::Lifetime(li) => { - let li = &li.lifetime; - params.extend(quote! { #li, }) - } - GenericParam::Const(_par) => todo!(), - }); - params.extend(quote! { > }); - params - } else { - quote! {} - } - }; - let where_clause = match item.generics.where_clause.clone() { - Some(mut clause) => { - let predicate = quote! { Self: Clone + Send + Sync + 'static }; - clause.predicates.push(syn::parse2(predicate).unwrap()); - Some(clause) - } - x => x, - }; - let out = parse_out_type(item.ident.span(), &item.attrs)?; - - let mut branches = quote! {}; - for variant in item.variants.iter() { - let handler = { - let handler_attr = variant - .attrs - .iter() - .find(|attr| attr.path.is_ident("handler")) - .ok_or_else(|| { - syn::Error::new( - variant.span(), - "Expected `handler` attribute.", - ) - })?; - handler_attr.parse_args::()? - }; - - branches.extend(match &variant.fields { - Fields::Named(fields) => create_branch_multiple_fields_named( - enum_ident, - &self_params, - &variant.ident, - &handler.func, - fields, - ), - Fields::Unnamed(fields) => match fields.unnamed.len() { - 1 => create_branch_one_field( - enum_ident, - &self_params, - &variant.ident, - &handler.func, - ), - len => create_branch_multiple_fields( - enum_ident, - &self_params, - &variant.ident, - &handler.func, - len, - ), - }, - Fields::Unit => create_branch_no_fields( - enum_ident, - &self_params, - &variant.ident, - &handler.func, - ), - }); - } - - Ok(quote! {const _: () = { - fn assert_clone() {} - - use teloxide::dptree; - use teloxide::dispatching::dialogue::Dialogue; - - impl #self_params_with_bounds teloxide::dispatching::HandlerFactory for #enum_ident #self_params #where_clause { - type Out = #out; - - fn handler() -> dptree::Handler<'static, dptree::di::DependencyMap, Self::Out, - teloxide::dispatching::DpHandlerDescription> { - assert_clone::<#enum_ident #self_params>(); - - dptree::entry() - #branches - } - } - };}) -} - -fn create_branch_no_fields( - state: &Ident, - state_generics: impl ToTokens, - kind: &Ident, - handler: &Path, -) -> TokenStream { - quote! { - .branch( - dptree::filter(|state: #state #state_generics| { - match state { #state::#kind => true, _ => false } - }).endpoint(#handler) - ) - } -} - -fn create_branch_one_field( - state: &Ident, - state_generics: impl ToTokens, - kind: &Ident, - handler: &Path, -) -> TokenStream { - quote! { - .branch( - dptree::filter_map(|state: #state #state_generics| { - match state { #state::#kind(arg) => Some(arg), _ => None } - }).endpoint(#handler) - ) - } -} - -fn create_branch_multiple_fields( - state: &Ident, - state_generics: impl ToTokens, - kind: &Ident, - handler: &Path, - fields_count: usize, -) -> TokenStream { - let fields = gen_variant_field_names(fields_count); - - quote! { - .branch( - dptree::filter_map(|state: #state #state_generics| { - match state { #state::#kind(#fields) => Some((#fields)), _ => None } - }).endpoint(#handler) - ) - } -} - -fn gen_variant_field_names(len: usize) -> TokenStream { - let mut fields = quote! {}; - - for i in 0..len { - let idx = format_ident!("_{}", i); - fields.extend(quote! { #idx, }); - } - - fields -} - -fn create_branch_multiple_fields_named( - state: &Ident, - state_generics: impl ToTokens, - kind: &Ident, - handler: &Path, - fields_named: &FieldsNamed, -) -> TokenStream { - let mut fields = quote! {}; - - for field in fields_named.named.iter() { - let ident = - field.ident.as_ref().expect("Named fields must have identifiers"); - fields.extend(quote! { #ident, }); - } - - quote! { - .branch( - dptree::filter_map(|state: #state #state_generics| { - match state { #state::#kind { #fields } => Some((#fields)), _ => None } - }).endpoint(#handler) - ) - } -} - -fn parse_out_type( - span: Span, - attrs: &[syn::Attribute], -) -> Result { - let mut out = None; - for x in attrs { - if x.path.is_ident("handler_out") { - out = Some(x.parse_args::()?); - } - } - if let Some(out) = out { - return Ok(out); - } - Err(syn::Error::new( - span, - "You must specify #[handler_out()] argument in which declare output \ - type of handlers. For example, #[handler_out(Result<(), Error>)]", - )) -} - -pub struct HandlerAttr { - func: Path, -} - -impl Parse for HandlerAttr { - fn parse(input: ParseStream) -> Result { - Ok(Self { func: input.parse::()? }) - } -} diff --git a/src/lib.rs b/src/lib.rs index 8baeaa34..fc20f3fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ mod attr; mod command; mod command_enum; -mod dialogue_state; mod fields_parse; mod rename_rules; @@ -18,17 +17,7 @@ use crate::{ }; use proc_macro::TokenStream; use quote::{quote, ToTokens}; -use syn::{parse_macro_input, DeriveInput, Fields, ItemEnum}; - -#[proc_macro_derive(DialogueState, attributes(handler, handler_out, store))] -#[deprecated(note = "Use teloxide::handler! instead")] -pub fn derive_dialogue_state(item: TokenStream) -> TokenStream { - let input = parse_macro_input!(item as ItemEnum); - match dialogue_state::expand(input) { - Ok(s) => s.into(), - Err(e) => e.to_compile_error().into(), - } -} +use syn::{parse_macro_input, DeriveInput, Fields}; macro_rules! get_or_return { ($($some:tt)*) => {