From c238906b69fd33d6856f57c4f231e1e8cbf16897 Mon Sep 17 00:00:00 2001 From: p0lunin Date: Mon, 24 Feb 2020 17:37:17 +0200 Subject: [PATCH] added impl_try_from function --- src/command.rs | 12 ++++++++++++ src/lib.rs | 30 ++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/command.rs b/src/command.rs index 921153ee..36496f26 100644 --- a/src/command.rs +++ b/src/command.rs @@ -2,6 +2,7 @@ use crate::{ attr::{Attr, BotCommandAttribute}, rename_rules::rename_by_rule, }; +use crate::enum_attributes::CommandEnum; pub struct Command { pub prefix: Option, @@ -30,6 +31,17 @@ impl Command { renamed, }) } + + pub fn get_matched_value(&self, global_parameters: &CommandEnum) -> String { + let prefix = if let Some(prefix) = &self.prefix { + prefix + } else if let Some(prefix) = &global_parameters.prefix { + prefix + } else { + "/" + }; + String::from(prefix) + &self.name + } } struct CommandAttrs { diff --git a/src/lib.rs b/src/lib.rs index fa3a408b..cf532aa0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ use crate::{ }; use proc_macro::TokenStream; use quote::{quote, ToTokens}; -use syn::{parse_macro_input, DeriveInput}; +use syn::{parse_macro_input, DeriveInput, Variant}; macro_rules! get_or_return { ($($some:tt)*) => { @@ -58,7 +58,6 @@ pub fn derive_telegram_command_enum(tokens: TokenStream) -> TokenStream { } } - let variant_ident = variants.iter().map(|variant| &variant.ident); let variant_name = variant_infos.iter().map(|info| { if info.renamed { info.name.clone() @@ -96,16 +95,11 @@ pub fn derive_telegram_command_enum(tokens: TokenStream) -> TokenStream { quote! {} }; + let fn_try_from = impl_try_parse_command(&variants, &variant_infos, &command_enum); + let expanded = quote! { impl BotCommand for #ident { - fn try_from(value: &str) -> Option { - match value { - #( - #variant_str1 => Some(Self::#variant_ident), - )* - _ => None - } - } + #fn_try_from fn descriptions() -> String { std::concat!(#global_description #(#variant_str2, #variant_description, '\n'),*).to_string() } @@ -133,6 +127,22 @@ pub fn derive_telegram_command_enum(tokens: TokenStream) -> TokenStream { TokenStream::from(expanded) } +fn impl_try_parse_command(variants: &[&Variant], infos: &[Command], global: &CommandEnum) -> impl ToTokens { + let matching_values = infos.iter().map(|c| c.get_matched_value(global)); + let variant_ident = variants.iter().map(|variant| &variant.ident); + + quote! { + fn try_from(value: &str) -> Option { + match value { + #( + #matching_values => Some(Self::#variant_ident), + )* + _ => None + } + } + } +} + fn get_enum_data(input: &DeriveInput) -> Result<&syn::DataEnum, TokenStream> { match &input.data { syn::Data::Enum(data) => Ok(data),