mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-23 06:51:01 +01:00
changed name of trait from TelegramCommandEnum to TelegramBotCommand and divided parse_command into parse_command and parse_command_with_prefix
This commit is contained in:
parent
4af7b9f1f0
commit
5f34d7ffc6
2 changed files with 79 additions and 26 deletions
|
@ -1,53 +1,106 @@
|
|||
pub use teloxide_macros::TelegramCommandEnum;
|
||||
pub use teloxide_macros::TelegramBotCommand;
|
||||
/// Enum for telegram commands
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::TelegramCommandEnum;
|
||||
/// use teloxide::utils::TelegramBotCommand;
|
||||
/// use teloxide::utils::parse_command_into_enum;
|
||||
/// #[derive(TelegramCommandEnum, PartialEq, Debug)]
|
||||
/// enum TelegramCommand {
|
||||
/// Start,
|
||||
/// Help,
|
||||
/// #[derive(TelegramBotCommand, PartialEq, Debug)]
|
||||
/// enum TelegramAdminCommand {
|
||||
/// Ban,
|
||||
/// Kick,
|
||||
/// }
|
||||
/// let (command, args) = parse_command_into_enum::<TelegramCommand>("/", "/start arg1 arg2").unwrap();
|
||||
/// assert_eq!(command, TelegramCommand::Start);
|
||||
/// assert_eq!(args, vec!["arg1", "arg2"]);
|
||||
/// let (command, args) = parse_command_into_enum::<TelegramAdminCommand>("/ban 5 h").unwrap();
|
||||
/// assert_eq!(command, TelegramAdminCommand::Ban);
|
||||
/// assert_eq!(args, vec!["5", "h"]);
|
||||
/// ```
|
||||
pub trait TelegramCommandEnum: Sized {
|
||||
pub trait TelegramBotCommand: Sized {
|
||||
fn try_from(s: &str) -> Option<Self>;
|
||||
}
|
||||
|
||||
pub fn parse_command_into_enum<'a, T>(
|
||||
/// Function to parse message with command into enum. Command must started with `/`
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::TelegramBotCommand;
|
||||
/// use teloxide::utils::parse_command_into_enum;
|
||||
/// #[derive(TelegramBotCommand, PartialEq, Debug)]
|
||||
/// enum TelegramAdminCommand {
|
||||
/// Ban,
|
||||
/// Kick,
|
||||
/// }
|
||||
/// let (command, args) = parse_command_into_enum::<TelegramAdminCommand>("/ban 5 h").unwrap();
|
||||
/// assert_eq!(command, TelegramAdminCommand::Ban);
|
||||
/// assert_eq!(args, vec!["5", "h"]);
|
||||
/// ```
|
||||
pub fn parse_command_into_enum<T>(
|
||||
text: &str,
|
||||
) -> Option<(T, Vec<&str>)>
|
||||
where
|
||||
T: TelegramBotCommand,
|
||||
{
|
||||
parse_command_into_enum_with_prefix("/", text)
|
||||
}
|
||||
|
||||
/// Function to parse message with command with custom prefix into enum.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::TelegramBotCommand;
|
||||
/// use teloxide::utils::parse_command_into_enum_with_prefix;
|
||||
/// #[derive(TelegramBotCommand, PartialEq, Debug)]
|
||||
/// enum TelegramAdminCommand {
|
||||
/// Ban,
|
||||
/// Kick,
|
||||
/// }
|
||||
/// let (command, args) = parse_command_into_enum_with_prefix::<TelegramAdminCommand>("!", "!ban 5 h").unwrap();
|
||||
/// assert_eq!(command, TelegramAdminCommand::Ban);
|
||||
/// assert_eq!(args, vec!["5", "h"]);
|
||||
/// ```
|
||||
pub fn parse_command_into_enum_with_prefix<'a, T>(
|
||||
prefix: &str,
|
||||
text: &'a str,
|
||||
) -> Option<(T, Vec<&'a str>)>
|
||||
where
|
||||
T: TelegramCommandEnum,
|
||||
T: TelegramBotCommand,
|
||||
{
|
||||
let (command, args) = parse_command(prefix,text)?;
|
||||
return match T::try_from(command) {
|
||||
let (command, args) = parse_command_with_prefix(prefix, text)?;
|
||||
match T::try_from(command) {
|
||||
Some(command) => Some((command, args)),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Function which parse string and return command with args
|
||||
/// Function which parse string and return command with args. It calls [`parse_command_with_prefix`] with default prefix `/`
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::parse_command;
|
||||
/// let text = "/ban 5 hours";
|
||||
/// let (command, args) = parse_command("/", text).unwrap();
|
||||
/// let (command, args) = parse_command(text).unwrap();
|
||||
/// assert_eq!(command, "ban");
|
||||
/// assert_eq!(args, vec!["5", "hours"]);
|
||||
/// ```
|
||||
pub fn parse_command<'a>(prefix: &str, text: &'a str) -> Option<(&'a str, Vec<&'a str>)> {
|
||||
pub fn parse_command(text: &str) -> Option<(&str, Vec<&str>)> {
|
||||
parse_command_with_prefix("/", text)
|
||||
}
|
||||
|
||||
/// Function which parse string and return command with args. Prefix - start symbols which denote start of command
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use teloxide::utils::parse_command_with_prefix;
|
||||
/// let text = "!ban 5 hours";
|
||||
/// let (command, args) = parse_command_with_prefix("!", text).unwrap();
|
||||
/// assert_eq!(command, "ban");
|
||||
/// assert_eq!(args, vec!["5", "hours"]);
|
||||
/// ```
|
||||
pub fn parse_command_with_prefix<'a>(prefix: &str, text: &'a str) -> Option<(&'a str, Vec<&'a str>)> {
|
||||
if !text.starts_with(prefix) {
|
||||
return None;
|
||||
}
|
||||
let mut words = text.split_whitespace();
|
||||
let command = &words.next()?[1..];
|
||||
let command = &words.next()?[prefix.len()..];
|
||||
Some((command, words.collect()))
|
||||
}
|
||||
|
||||
|
@ -59,7 +112,7 @@ mod tests {
|
|||
fn parse_command_with_args_() {
|
||||
let data = "/command arg1 arg2";
|
||||
let expected = Some(("command", vec!["arg1", "arg2"]));
|
||||
let actual = parse_command("/", data);
|
||||
let actual = parse_command(data);
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
|
@ -67,13 +120,13 @@ mod tests {
|
|||
fn parse_command_with_args_without_args() {
|
||||
let data = "/command";
|
||||
let expected = Some(("command", vec![]));
|
||||
let actual = parse_command("/", data);
|
||||
let actual = parse_command(data);
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_command__with_args() {
|
||||
#[derive(TelegramCommandEnum, Debug, PartialEq)]
|
||||
#[derive(TelegramBotCommand, Debug, PartialEq)]
|
||||
enum DefaultCommands {
|
||||
Start,
|
||||
Help,
|
||||
|
@ -81,7 +134,7 @@ mod tests {
|
|||
|
||||
let data = "/start arg1 arg2";
|
||||
let expected = Some((DefaultCommands::Start, vec!["arg1", "arg2"]));
|
||||
let actual = parse_command_into_enum::<DefaultCommands>("/", data);
|
||||
let actual = parse_command_into_enum::<DefaultCommands>(data);
|
||||
assert_eq!(actual, expected)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use proc_macro::TokenStream;
|
|||
use quote::quote;
|
||||
use syn::{DeriveInput, parse_macro_input};
|
||||
|
||||
#[proc_macro_derive(TelegramCommandEnum)]
|
||||
#[proc_macro_derive(TelegramBotCommand)]
|
||||
pub fn derive_telegram_command_enum(tokens: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(tokens as DeriveInput);
|
||||
|
||||
|
@ -15,13 +15,13 @@ pub fn derive_telegram_command_enum(tokens: TokenStream) -> TokenStream {
|
|||
variant.ident.to_string().to_lowercase()
|
||||
}))
|
||||
}
|
||||
_ => panic!("TelegramCommandEnum allowed only for enums")
|
||||
_ => return TokenStream::from(quote! { compile_error!("TelegramBotCommand allowed only for enums") })
|
||||
};
|
||||
|
||||
let ident = input.ident;
|
||||
|
||||
let expanded = quote! {
|
||||
impl TelegramCommandEnum for #ident {
|
||||
impl TelegramBotCommand for #ident {
|
||||
fn try_from(value: &str) -> Option<Self> {
|
||||
match value {
|
||||
#(
|
||||
|
|
Loading…
Reference in a new issue