Merge pull request #724 from teloxide/concrete-error-type-repls

Use `RequestError` in REPLs

Former-commit-id: 4246455ccd
This commit is contained in:
Hirrolot 2022-10-03 15:33:09 +06:00 committed by GitHub
commit 2bdea18ec3
11 changed files with 39 additions and 59 deletions

View file

@ -13,12 +13,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `UpdateListener` now has an associated type `Err` instead of a generic - `UpdateListener` now has an associated type `Err` instead of a generic
- `AsUpdateStream` now has an associated type `StreamErr` instead of a generic - `AsUpdateStream` now has an associated type `StreamErr` instead of a generic
- Rename `dispatching::stop_token::{AsyncStopToken, AsyncStopFlag}` => `stop::{StopToken, StopFlag}` - Rename `dispatching::stop_token::{AsyncStopToken, AsyncStopFlag}` => `stop::{StopToken, StopFlag}`
- Replace the generic error type `E` with `RequestError` for REPLs (`repl(_with_listener)`, `commands_repl(_with_listener)`)
- The following functions are now `#[must_use]`: - The following functions are now `#[must_use]`:
- `BotCommands::ty`. - `BotCommands::ty`.
- `CommandDescriptions::{new, global_description, username, username_from_me}`. - `CommandDescriptions::{new, global_description, username, username_from_me}`.
- `teloxide::filter_command`. - `teloxide::filter_command`.
- `teloxide::dispatching::dialogue::enter`. - `teloxide::dispatching::dialogue::enter`.
### Added
- `requests::ResponseResult` to `prelude`
### Removed ### Removed
- `dispatching::stop_token::StopToken` trait (all uses are replaced with `stop::StopToken` structure) - `dispatching::stop_token::StopToken` trait (all uses are replaced with `stop::StopToken` structure)

View file

@ -96,7 +96,7 @@ async fn main() {
teloxide::repl(bot, |message: Message, bot: Bot| async move { teloxide::repl(bot, |message: Message, bot: Bot| async move {
bot.send_dice(message.chat.id).await?; bot.send_dice(message.chat.id).await?;
respond(()) Ok(())
}) })
.await; .await;
} }
@ -122,8 +122,6 @@ Commands are strongly typed and defined declaratively, similar to how we define
```rust,no_run ```rust,no_run
use teloxide::{prelude::*, utils::command::BotCommands}; use teloxide::{prelude::*, utils::command::BotCommands};
use std::error::Error;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
pretty_env_logger::init(); pretty_env_logger::init();
@ -145,11 +143,7 @@ enum Command {
UsernameAndAge { username: String, age: u8 }, UsernameAndAge { username: String, age: u8 },
} }
async fn answer( async fn answer(bot: Bot, message: Message, command: Command) -> ResponseResult<()> {
bot: Bot,
message: Message,
command: Command,
) -> Result<(), Box<dyn Error + Send + Sync>> {
match command { match command {
Command::Help => { Command::Help => {
bot.send_message(message.chat.id, Command::descriptions().to_string()).await? bot.send_message(message.chat.id, Command::descriptions().to_string()).await?

View file

@ -1,4 +1,4 @@
use std::{error::Error, str::FromStr}; use std::str::FromStr;
use chrono::Duration; use chrono::Duration;
use teloxide::{prelude::*, types::ChatPermissions, utils::command::BotCommands}; use teloxide::{prelude::*, types::ChatPermissions, utils::command::BotCommands};
@ -63,11 +63,7 @@ async fn main() {
teloxide::commands_repl(bot, action, Command::ty()).await; teloxide::commands_repl(bot, action, Command::ty()).await;
} }
async fn action( async fn action(bot: Bot, msg: Message, command: Command) -> ResponseResult<()> {
bot: Bot,
msg: Message,
command: Command,
) -> Result<(), Box<dyn Error + Send + Sync>> {
match command { match command {
Command::Help => { Command::Help => {
bot.send_message(msg.chat.id, Command::descriptions().to_string()).await?; bot.send_message(msg.chat.id, Command::descriptions().to_string()).await?;
@ -81,7 +77,7 @@ async fn action(
} }
// Kick a user with a replied message. // Kick a user with a replied message.
async fn kick_user(bot: Bot, msg: Message) -> Result<(), Box<dyn Error + Send + Sync>> { async fn kick_user(bot: Bot, msg: Message) -> ResponseResult<()> {
match msg.reply_to_message() { match msg.reply_to_message() {
Some(replied) => { Some(replied) => {
// bot.unban_chat_member can also kicks a user from a group chat. // bot.unban_chat_member can also kicks a user from a group chat.
@ -95,11 +91,7 @@ async fn kick_user(bot: Bot, msg: Message) -> Result<(), Box<dyn Error + Send +
} }
// Ban a user with replied message. // Ban a user with replied message.
async fn ban_user( async fn ban_user(bot: Bot, msg: Message, time: Duration) -> ResponseResult<()> {
bot: Bot,
msg: Message,
time: Duration,
) -> Result<(), Box<dyn Error + Send + Sync>> {
match msg.reply_to_message() { match msg.reply_to_message() {
Some(replied) => { Some(replied) => {
bot.kick_chat_member( bot.kick_chat_member(
@ -118,11 +110,7 @@ async fn ban_user(
} }
// Mute a user with a replied message. // Mute a user with a replied message.
async fn mute_user( async fn mute_user(bot: Bot, msg: Message, time: Duration) -> ResponseResult<()> {
bot: Bot,
msg: Message,
time: Duration,
) -> Result<(), Box<dyn Error + Send + Sync>> {
match msg.reply_to_message() { match msg.reply_to_message() {
Some(replied) => { Some(replied) => {
bot.restrict_chat_member( bot.restrict_chat_member(

View file

@ -1,7 +1,5 @@
use teloxide::{prelude::*, utils::command::BotCommands}; use teloxide::{prelude::*, utils::command::BotCommands};
use std::error::Error;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
pretty_env_logger::init(); pretty_env_logger::init();
@ -23,11 +21,7 @@ enum Command {
UsernameAndAge { username: String, age: u8 }, UsernameAndAge { username: String, age: u8 },
} }
async fn answer( async fn answer(bot: Bot, message: Message, command: Command) -> ResponseResult<()> {
bot: Bot,
message: Message,
command: Command,
) -> Result<(), Box<dyn Error + Send + Sync>> {
match command { match command {
Command::Help => { Command::Help => {
bot.send_message(message.chat.id, Command::descriptions().to_string()).await? bot.send_message(message.chat.id, Command::descriptions().to_string()).await?

View file

@ -49,7 +49,7 @@ async fn main() {
bot, bot,
|msg: Message, bot: Bot| async move { |msg: Message, bot: Bot| async move {
bot.send_message(msg.chat.id, "pong").await?; bot.send_message(msg.chat.id, "pong").await?;
respond(()) Ok(())
}, },
listener, listener,
) )

View file

@ -20,7 +20,7 @@ async fn main() {
bot, bot,
|msg: Message, bot: Bot| async move { |msg: Message, bot: Bot| async move {
bot.send_message(msg.chat.id, "pong").await?; bot.send_message(msg.chat.id, "pong").await?;
respond(()) Ok(())
}, },
listener, listener,
) )

View file

@ -11,7 +11,7 @@ async fn main() {
teloxide::repl(bot, |message: Message, bot: Bot| async move { teloxide::repl(bot, |message: Message, bot: Bot| async move {
bot.send_dice(message.chat.id).await?; bot.send_dice(message.chat.id).await?;
respond(()) Ok(())
}) })
.await; .await;
} }

View file

@ -5,6 +5,7 @@ use crate::{
error_handlers::LoggingErrorHandler, error_handlers::LoggingErrorHandler,
types::Update, types::Update,
utils::command::BotCommands, utils::command::BotCommands,
RequestError,
}; };
use dptree::di::{DependencyMap, Injectable}; use dptree::di::{DependencyMap, Injectable};
use std::{fmt::Debug, marker::PhantomData}; use std::{fmt::Debug, marker::PhantomData};
@ -34,13 +35,12 @@ use teloxide_core::requests::Requester;
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop /// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
/// [`Dispatcher`]: crate::dispatching::Dispatcher /// [`Dispatcher`]: crate::dispatching::Dispatcher
#[cfg(feature = "ctrlc_handler")] #[cfg(feature = "ctrlc_handler")]
pub async fn commands_repl<'a, R, Cmd, H, E, Args>(bot: R, handler: H, cmd: PhantomData<Cmd>) pub async fn commands_repl<'a, R, Cmd, H, Args>(bot: R, handler: H, cmd: PhantomData<Cmd>)
where where
Cmd: BotCommands + Send + Sync + 'static, Cmd: BotCommands + Send + Sync + 'static,
H: Injectable<DependencyMap, Result<(), E>, Args> + Send + Sync + 'static, H: Injectable<DependencyMap, Result<(), RequestError>, Args> + Send + Sync + 'static,
R: Requester + Clone + Send + Sync + 'static, R: Requester + Clone + Send + Sync + 'static,
<R as Requester>::GetUpdates: Send, <R as Requester>::GetUpdates: Send,
E: Debug + Send + Sync + 'static,
{ {
let cloned_bot = bot.clone(); let cloned_bot = bot.clone();
@ -78,18 +78,17 @@ where
/// [`commands_repl`]: crate::dispatching::repls::commands_repl() /// [`commands_repl`]: crate::dispatching::repls::commands_repl()
/// [`UpdateListener`]: crate::dispatching::update_listeners::UpdateListener /// [`UpdateListener`]: crate::dispatching::update_listeners::UpdateListener
#[cfg(feature = "ctrlc_handler")] #[cfg(feature = "ctrlc_handler")]
pub async fn commands_repl_with_listener<'a, R, Cmd, H, L, E, Args>( pub async fn commands_repl_with_listener<'a, R, Cmd, H, L, Args>(
bot: R, bot: R,
handler: H, handler: H,
listener: L, listener: L,
_cmd: PhantomData<Cmd>, _cmd: PhantomData<Cmd>,
) where ) where
Cmd: BotCommands + Send + Sync + 'static, Cmd: BotCommands + Send + Sync + 'static,
H: Injectable<DependencyMap, Result<(), E>, Args> + Send + Sync + 'static, H: Injectable<DependencyMap, Result<(), RequestError>, Args> + Send + Sync + 'static,
L: UpdateListener + Send + 'a, L: UpdateListener + Send + 'a,
L::Err: Debug + Send + 'a, L::Err: Debug + Send + 'a,
R: Requester + Clone + Send + Sync + 'static, R: Requester + Clone + Send + Sync + 'static,
E: Debug + Send + Sync + 'static,
{ {
use crate::dispatching::Dispatcher; use crate::dispatching::Dispatcher;

View file

@ -1,7 +1,8 @@
use crate::{ use crate::{
dispatching::{update_listeners, update_listeners::UpdateListener, UpdateFilterExt}, dispatching::{update_listeners, update_listeners::UpdateListener, UpdateFilterExt},
error_handlers::{LoggingErrorHandler, OnError}, error_handlers::LoggingErrorHandler,
types::Update, types::Update,
RequestError,
}; };
use dptree::di::{DependencyMap, Injectable}; use dptree::di::{DependencyMap, Injectable};
use std::fmt::Debug; use std::fmt::Debug;
@ -27,11 +28,9 @@ use teloxide_core::requests::Requester;
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop /// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
/// [`Dispatcher`]: crate::dispatching::Dispatcher /// [`Dispatcher`]: crate::dispatching::Dispatcher
#[cfg(feature = "ctrlc_handler")] #[cfg(feature = "ctrlc_handler")]
pub async fn repl<R, H, E, Args>(bot: R, handler: H) pub async fn repl<R, H, Args>(bot: R, handler: H)
where where
H: Injectable<DependencyMap, Result<(), E>, Args> + Send + Sync + 'static, H: Injectable<DependencyMap, Result<(), RequestError>, Args> + Send + Sync + 'static,
Result<(), E>: OnError<E>,
E: Debug + Send + Sync + 'static,
R: Requester + Send + Sync + Clone + 'static, R: Requester + Send + Sync + Clone + 'static,
<R as Requester>::GetUpdates: Send, <R as Requester>::GetUpdates: Send,
{ {
@ -60,13 +59,11 @@ where
/// [`repl`]: crate::dispatching::repls::repl() /// [`repl`]: crate::dispatching::repls::repl()
/// [`UpdateListener`]: crate::dispatching::update_listeners::UpdateListener /// [`UpdateListener`]: crate::dispatching::update_listeners::UpdateListener
#[cfg(feature = "ctrlc_handler")] #[cfg(feature = "ctrlc_handler")]
pub async fn repl_with_listener<'a, R, H, E, L, Args>(bot: R, handler: H, listener: L) pub async fn repl_with_listener<'a, R, H, L, Args>(bot: R, handler: H, listener: L)
where where
H: Injectable<DependencyMap, Result<(), E>, Args> + Send + Sync + 'static, H: Injectable<DependencyMap, Result<(), RequestError>, Args> + Send + Sync + 'static,
L: UpdateListener + Send + 'a, L: UpdateListener + Send + 'a,
L::Err: Debug, L::Err: Debug,
Result<(), E>: OnError<E>,
E: Debug + Send + Sync + 'static,
R: Requester + Clone + Send + Sync + 'static, R: Requester + Clone + Send + Sync + 'static,
{ {
use crate::dispatching::Dispatcher; use crate::dispatching::Dispatcher;
@ -89,7 +86,7 @@ where
#[test] #[test]
fn repl_is_send() { fn repl_is_send() {
let bot = crate::Bot::new(""); let bot = crate::Bot::new("");
let repl = crate::repl(bot, || async { crate::respond(()) }); let repl = crate::repl(bot, || async { Ok(()) });
assert_send(&repl); assert_send(&repl);
fn assert_send(_: &impl Send) {} fn assert_send(_: &impl Send) {}

View file

@ -17,7 +17,7 @@
//! //!
//! teloxide::repl(bot, |message: Message, bot: Bot| async move { //! teloxide::repl(bot, |message: Message, bot: Bot| async move {
//! bot.send_dice(message.chat.id).await?; //! bot.send_dice(message.chat.id).await?;
//! respond(()) //! Ok(())
//! }) //! })
//! .await; //! .await;
//! # } //! # }

View file

@ -1,17 +1,20 @@
//! Commonly used items. //! Commonly used items.
pub use crate::{ pub use crate::error_handlers::{LoggingErrorHandler, OnError};
error_handlers::{LoggingErrorHandler, OnError},
respond, #[allow(deprecated)]
}; pub use crate::respond;
pub use crate::dispatching::{ pub use crate::dispatching::{
dialogue::Dialogue, Dispatcher, HandlerExt as _, MessageFilterExt as _, UpdateFilterExt as _, dialogue::Dialogue, Dispatcher, HandlerExt as _, MessageFilterExt as _, UpdateFilterExt as _,
}; };
pub use teloxide_core::types::{ pub use teloxide_core::{
CallbackQuery, ChatMemberUpdated, ChosenInlineResult, InlineQuery, Message, Poll, PollAnswer, requests::ResponseResult,
PreCheckoutQuery, ShippingQuery, Update, types::{
CallbackQuery, ChatMemberUpdated, ChosenInlineResult, InlineQuery, Message, Poll,
PollAnswer, PreCheckoutQuery, ShippingQuery, Update,
},
}; };
#[cfg(feature = "auto-send")] #[cfg(feature = "auto-send")]