This commit is contained in:
p0lunin 2020-04-25 20:16:27 +03:00
parent 0ede19c684
commit d5f3864921
3 changed files with 30 additions and 17 deletions

View file

@ -45,7 +45,7 @@ futures = "0.3.1"
pin-project = "0.4.6" pin-project = "0.4.6"
serde_with_macros = "1.0.1" serde_with_macros = "1.0.1"
teloxide-macros = "0.2.1" teloxide-macros = {git="https://github.com/teloxide/teloxide-macros", branch="dev"}
[dev-dependencies] [dev-dependencies]
smart-default = "0.6.0" smart-default = "0.6.0"

View file

@ -19,7 +19,7 @@ pub trait DispatcherHandlerRxExt {
fn commands<C, N>( fn commands<C, N>(
self, self,
bot_name: N, bot_name: N,
) -> BoxStream<'static, (DispatcherHandlerCx<Message>, C, Vec<String>)> ) -> BoxStream<'static, (DispatcherHandlerCx<Message>, C)>
where where
Self: Stream<Item = DispatcherHandlerCx<Message>>, Self: Stream<Item = DispatcherHandlerCx<Message>>,
C: BotCommand, C: BotCommand,
@ -44,7 +44,7 @@ where
fn commands<C, N>( fn commands<C, N>(
self, self,
bot_name: N, bot_name: N,
) -> BoxStream<'static, (DispatcherHandlerCx<Message>, C, Vec<String>)> ) -> BoxStream<'static, (DispatcherHandlerCx<Message>, C)>
where where
Self: Stream<Item = DispatcherHandlerCx<Message>>, Self: Stream<Item = DispatcherHandlerCx<Message>>,
C: BotCommand, C: BotCommand,
@ -56,13 +56,10 @@ where
let bot_name = bot_name.clone(); let bot_name = bot_name.clone();
async move { async move {
C::parse(&text, &bot_name).map(|(command, args)| { C::parse(&text, &bot_name).map(|command| {
( (
cx, cx,
command, command,
args.into_iter()
.map(ToOwned::to_owned)
.collect::<Vec<String>>(),
) )
}) })
} }

View file

@ -57,6 +57,7 @@
//! [examples/admin_bot]: https://github.com/teloxide/teloxide/blob/master/examples/miltiple_handlers_bot/ //! [examples/admin_bot]: https://github.com/teloxide/teloxide/blob/master/examples/miltiple_handlers_bot/
pub use teloxide_macros::BotCommand; pub use teloxide_macros::BotCommand;
use std::str::FromStr;
/// An enumeration of bot's commands. /// An enumeration of bot's commands.
/// ///
@ -100,13 +101,28 @@ pub use teloxide_macros::BotCommand;
/// ///
/// All variant attributes overlap the `enum` attributes. /// All variant attributes overlap the `enum` attributes.
pub trait BotCommand: Sized { pub trait BotCommand: Sized {
fn try_from(s: &str) -> Option<Self>;
fn descriptions() -> String; fn descriptions() -> String;
fn parse<N>(s: &str, bot_name: N) -> Option<(Self, Vec<&str>)> fn parse<N>(s: &str, bot_name: N) -> Option<Self>
where where
N: Into<String>; N: Into<String>;
} }
pub trait CommandArgument {
fn parse(args: &mut String) -> Option<Self> where Self: Sized;
}
impl<T: FromStr> CommandArgument for T {
fn parse(args: &mut String) -> Option<Self> {
match T::from_str(&args) {
Ok(res) => {
args.clear();
Some(res)
}
Err(_) => None
}
}
}
/// Parses a string into a command with args. /// Parses a string into a command with args.
/// ///
/// It calls [`parse_command_with_prefix`] with the default prefix `/`. /// It calls [`parse_command_with_prefix`] with the default prefix `/`.
@ -191,12 +207,12 @@ mod tests {
#[command(rename = "lowercase")] #[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)] #[derive(BotCommand, Debug, PartialEq)]
enum DefaultCommands { enum DefaultCommands {
Start, Start(String),
Help, Help,
} }
let data = "/start arg1 arg2"; let data = "/start arg1 arg2";
let expected = Some((DefaultCommands::Start, vec!["arg1", "arg2"])); let expected = Some(DefaultCommands::Start("arg1 arg2".to_string()));
let actual = DefaultCommands::parse(data, ""); let actual = DefaultCommands::parse(data, "");
assert_eq!(actual, expected) assert_eq!(actual, expected)
} }
@ -207,12 +223,12 @@ mod tests {
#[derive(BotCommand, Debug, PartialEq)] #[derive(BotCommand, Debug, PartialEq)]
enum DefaultCommands { enum DefaultCommands {
#[command(prefix = "!")] #[command(prefix = "!")]
Start, Start(String),
Help, Help,
} }
let data = "!start arg1 arg2"; let data = "!start arg1 arg2";
let expected = Some((DefaultCommands::Start, vec!["arg1", "arg2"])); let expected = Some(DefaultCommands::Start("arg1 arg2".to_string()));
let actual = DefaultCommands::parse(data, ""); let actual = DefaultCommands::parse(data, "");
assert_eq!(actual, expected) assert_eq!(actual, expected)
} }
@ -229,7 +245,7 @@ mod tests {
assert_eq!( assert_eq!(
DefaultCommands::Start, DefaultCommands::Start,
DefaultCommands::parse("!start", "").unwrap().0 DefaultCommands::parse("!start", "").unwrap()
); );
assert_eq!(DefaultCommands::descriptions(), "!start - desc\n/help\n"); assert_eq!(DefaultCommands::descriptions(), "!start - desc\n/help\n");
} }
@ -250,11 +266,11 @@ mod tests {
assert_eq!( assert_eq!(
DefaultCommands::Start, DefaultCommands::Start,
DefaultCommands::parse("/start", "MyNameBot").unwrap().0 DefaultCommands::parse("/start", "MyNameBot").unwrap()
); );
assert_eq!( assert_eq!(
DefaultCommands::Help, DefaultCommands::Help,
DefaultCommands::parse("!help", "MyNameBot").unwrap().0 DefaultCommands::parse("!help", "MyNameBot").unwrap()
); );
assert_eq!( assert_eq!(
DefaultCommands::descriptions(), DefaultCommands::descriptions(),
@ -274,7 +290,7 @@ mod tests {
assert_eq!( assert_eq!(
DefaultCommands::Start, DefaultCommands::Start,
DefaultCommands::parse("/start@MyNameBot", "MyNameBot").unwrap().0 DefaultCommands::parse("/start@MyNameBot", "MyNameBot").unwrap()
); );
} }
} }