mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 22:46:39 +01:00
parent
eece564727
commit
f54db300ed
8 changed files with 174 additions and 6 deletions
|
@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## unreleased
|
## unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `teloxide::dispatching::repls::CommandRepl`, `teloxide::prelude::CommandRepl` ([issue #740](https://github.com/teloxide/teloxide/issues/740))
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
- `teloxide::dispatching::repls::{commands_repl, commands_repl_with_listener}` (use `CommandRepl` instead)
|
||||||
|
|
||||||
## 0.11.0 - 2022-10-07
|
## 0.11.0 - 2022-10-07
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
This document describes breaking changes of `teloxide` crate, as well as the ways to update code.
|
This document describes breaking changes of `teloxide` crate, as well as the ways to update code.
|
||||||
Note that the list of required changes is not fully exhaustive and it may lack something in rare cases.
|
Note that the list of required changes is not fully exhaustive and it may lack something in rare cases.
|
||||||
|
|
||||||
|
## 0.10 -> 0.xxx.xxx
|
||||||
|
|
||||||
|
### teloxide
|
||||||
|
|
||||||
|
We have introduced the new trait `CommandRepl` that replaces the old `commands_repl_(with_listener)` functions:
|
||||||
|
|
||||||
|
```diff,rust
|
||||||
|
- teloxide::commands_repl(bot, answer, Command::ty())
|
||||||
|
+ Command::repl(bot, answer)
|
||||||
|
```
|
||||||
|
|
||||||
|
```diff,rust
|
||||||
|
- teloxide::commands_repl_with_listener(bot, answer, listener, Command::ty())
|
||||||
|
+ Command::repl_with_listener(bot, answer, listener)
|
||||||
|
```
|
||||||
|
|
||||||
## 0.10 -> 0.11
|
## 0.10 -> 0.11
|
||||||
|
|
||||||
### core
|
### core
|
||||||
|
|
|
@ -60,7 +60,7 @@ async fn main() {
|
||||||
|
|
||||||
let bot = teloxide::Bot::from_env();
|
let bot = teloxide::Bot::from_env();
|
||||||
|
|
||||||
teloxide::commands_repl(bot, action, Command::ty()).await;
|
Command::repl(bot, action).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn action(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
|
async fn action(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
|
||||||
|
|
|
@ -7,7 +7,7 @@ async fn main() {
|
||||||
|
|
||||||
let bot = Bot::from_env();
|
let bot = Bot::from_env();
|
||||||
|
|
||||||
teloxide::commands_repl(bot, answer, Command::ty()).await;
|
Command::repl(bot, answer).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(BotCommands, Clone)]
|
#[derive(BotCommands, Clone)]
|
||||||
|
|
|
@ -11,5 +11,7 @@
|
||||||
mod commands_repl;
|
mod commands_repl;
|
||||||
mod repl;
|
mod repl;
|
||||||
|
|
||||||
|
pub use commands_repl::CommandRepl;
|
||||||
|
#[allow(deprecated)]
|
||||||
pub use commands_repl::{commands_repl, commands_repl_with_listener};
|
pub use commands_repl::{commands_repl, commands_repl_with_listener};
|
||||||
pub use repl::{repl, repl_with_listener};
|
pub use repl::{repl, repl_with_listener};
|
||||||
|
|
|
@ -8,8 +8,145 @@ use crate::{
|
||||||
utils::command::BotCommands,
|
utils::command::BotCommands,
|
||||||
};
|
};
|
||||||
use dptree::di::{DependencyMap, Injectable};
|
use dptree::di::{DependencyMap, Injectable};
|
||||||
|
use futures::future::BoxFuture;
|
||||||
use std::{fmt::Debug, marker::PhantomData};
|
use std::{fmt::Debug, marker::PhantomData};
|
||||||
|
|
||||||
|
/// A [REPL] for commands.
|
||||||
|
///
|
||||||
|
/// REPLs are meant only for simple bots and rapid prototyping. If you need to
|
||||||
|
/// supply dependencies or describe more complex dispatch logic, please use
|
||||||
|
/// [`Dispatcher`]. See also: ["Dispatching or
|
||||||
|
/// REPLs?"](../index.html#dispatching-or-repls).
|
||||||
|
///
|
||||||
|
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
|
///
|
||||||
|
/// All errors from the handler and update listener will be logged.
|
||||||
|
///
|
||||||
|
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
||||||
|
///
|
||||||
|
/// This trait extends your [`BotCommands`] type with REPL facilities.
|
||||||
|
///
|
||||||
|
/// ## Signatures
|
||||||
|
///
|
||||||
|
/// Don't be scared by many trait bounds in the signatures, in essence they
|
||||||
|
/// require:
|
||||||
|
///
|
||||||
|
/// 1. `bot` is a bot, client for the Telegram bot API. It is represented via
|
||||||
|
/// the [`Requester`] trait.
|
||||||
|
/// 2. `handler` is an `async` function that takes arguments from
|
||||||
|
/// [`DependencyMap`] (see below) and returns [`ResponseResult`].
|
||||||
|
/// 3. `listener` is something that takes updates from a Telegram server and
|
||||||
|
/// implements [`UpdateListener`].
|
||||||
|
///
|
||||||
|
/// All the other requirements are about thread safety and data validity and can
|
||||||
|
/// be ignored for most of the time.
|
||||||
|
///
|
||||||
|
/// ## Handler arguments
|
||||||
|
///
|
||||||
|
/// `teloxide` provides the following types to the `handler`:
|
||||||
|
/// - [`Message`]
|
||||||
|
/// - `R` (type of the `bot`)
|
||||||
|
/// - `Cmd` (type of the parsed command)
|
||||||
|
/// - [`Me`]
|
||||||
|
///
|
||||||
|
/// Each of these types can be accepted as a handler parameter. Note that they
|
||||||
|
/// aren't all required at the same time: e.g., you can take only the bot and
|
||||||
|
/// the command without [`Me`] and [`Message`].
|
||||||
|
///
|
||||||
|
/// [`Me`]: crate::types::Me
|
||||||
|
/// [`Message`]: crate::types::Message
|
||||||
|
///
|
||||||
|
/// ## Stopping
|
||||||
|
//
|
||||||
|
#[doc = include_str!("stopping.md")]
|
||||||
|
///
|
||||||
|
/// ## Caution
|
||||||
|
//
|
||||||
|
#[doc = include_str!("caution.md")]
|
||||||
|
///
|
||||||
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
|
pub trait CommandRepl {
|
||||||
|
/// A REPL for commands.
|
||||||
|
///
|
||||||
|
/// See [`CommandRepl`] for more details.
|
||||||
|
fn repl<'a, R, H, Args>(bot: R, handler: H) -> BoxFuture<'a, ()>
|
||||||
|
where
|
||||||
|
R: Requester + Clone + Send + Sync + 'static,
|
||||||
|
<R as Requester>::GetUpdates: Send,
|
||||||
|
<R as Requester>::GetWebhookInfo: Send,
|
||||||
|
<R as Requester>::GetMe: Send,
|
||||||
|
<R as Requester>::DeleteWebhook: Send,
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static;
|
||||||
|
|
||||||
|
/// A REPL for commands with a custom [`UpdateListener`].
|
||||||
|
///
|
||||||
|
/// See [`CommandRepl`] for more details.
|
||||||
|
fn repl_with_listener<'a, R, H, L, Args>(bot: R, handler: H, listener: L) -> BoxFuture<'a, ()>
|
||||||
|
where
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static,
|
||||||
|
L: UpdateListener + Send + 'a,
|
||||||
|
L::Err: Debug + Send + 'a,
|
||||||
|
R: Requester + Clone + Send + Sync + 'static,
|
||||||
|
<R as Requester>::GetMe: Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
|
impl<Cmd> CommandRepl for Cmd
|
||||||
|
where
|
||||||
|
Cmd: BotCommands + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
fn repl<'a, R, H, Args>(bot: R, handler: H) -> BoxFuture<'a, ()>
|
||||||
|
where
|
||||||
|
R: Requester + Clone + Send + Sync + 'static,
|
||||||
|
<R as Requester>::GetUpdates: Send,
|
||||||
|
<R as Requester>::GetWebhookInfo: Send,
|
||||||
|
<R as Requester>::GetMe: Send,
|
||||||
|
<R as Requester>::DeleteWebhook: Send,
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
let cloned_bot = bot.clone();
|
||||||
|
|
||||||
|
Box::pin(async move {
|
||||||
|
Self::repl_with_listener(
|
||||||
|
bot,
|
||||||
|
handler,
|
||||||
|
update_listeners::polling_default(cloned_bot).await,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn repl_with_listener<'a, R, H, L, Args>(bot: R, handler: H, listener: L) -> BoxFuture<'a, ()>
|
||||||
|
where
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static,
|
||||||
|
L: UpdateListener + Send + 'a,
|
||||||
|
L::Err: Debug + Send + 'a,
|
||||||
|
R: Requester + Clone + Send + Sync + 'static,
|
||||||
|
<R as Requester>::GetMe: Send,
|
||||||
|
{
|
||||||
|
use crate::dispatching::Dispatcher;
|
||||||
|
|
||||||
|
// Other update types are of no interest to use since this REPL is only for
|
||||||
|
// commands. See <https://github.com/teloxide/teloxide/issues/557>.
|
||||||
|
let ignore_update = |_upd| Box::pin(async {});
|
||||||
|
|
||||||
|
Box::pin(async move {
|
||||||
|
Dispatcher::builder(
|
||||||
|
bot,
|
||||||
|
Update::filter_message().filter_command::<Cmd>().endpoint(handler),
|
||||||
|
)
|
||||||
|
.default_handler(ignore_update)
|
||||||
|
.enable_ctrlc_handler()
|
||||||
|
.build()
|
||||||
|
.dispatch_with_listener(
|
||||||
|
listener,
|
||||||
|
LoggingErrorHandler::with_custom_text("An error from the update listener"),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A [REPL] for commands.
|
/// A [REPL] for commands.
|
||||||
//
|
//
|
||||||
///
|
///
|
||||||
|
@ -59,6 +196,7 @@ use std::{fmt::Debug, marker::PhantomData};
|
||||||
#[doc = include_str!("caution.md")]
|
#[doc = include_str!("caution.md")]
|
||||||
///
|
///
|
||||||
#[cfg(feature = "ctrlc_handler")]
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
|
#[deprecated(note = "Use `CommandsRepl::repl` instead")]
|
||||||
pub async fn commands_repl<'a, R, Cmd, H, 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
|
||||||
R: Requester + Clone + Send + Sync + 'static,
|
R: Requester + Clone + Send + Sync + 'static,
|
||||||
|
@ -68,6 +206,7 @@ where
|
||||||
{
|
{
|
||||||
let cloned_bot = bot.clone();
|
let cloned_bot = bot.clone();
|
||||||
|
|
||||||
|
#[allow(deprecated)]
|
||||||
commands_repl_with_listener(
|
commands_repl_with_listener(
|
||||||
bot,
|
bot,
|
||||||
handler,
|
handler,
|
||||||
|
@ -127,6 +266,7 @@ where
|
||||||
#[doc = include_str!("caution.md")]
|
#[doc = include_str!("caution.md")]
|
||||||
///
|
///
|
||||||
#[cfg(feature = "ctrlc_handler")]
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
|
#[deprecated(note = "Use `CommandsRepl::repl_with_listener` instead")]
|
||||||
pub async fn commands_repl_with_listener<'a, R, Cmd, H, L, Args>(
|
pub async fn commands_repl_with_listener<'a, R, Cmd, H, L, Args>(
|
||||||
bot: R,
|
bot: R,
|
||||||
handler: H,
|
handler: H,
|
||||||
|
|
|
@ -58,9 +58,10 @@
|
||||||
#![allow(clippy::nonstandard_macro_braces)]
|
#![allow(clippy::nonstandard_macro_braces)]
|
||||||
|
|
||||||
#[cfg(feature = "ctrlc_handler")]
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
pub use dispatching::repls::{
|
pub use dispatching::repls::{repl, repl_with_listener};
|
||||||
commands_repl, commands_repl_with_listener, repl, repl_with_listener,
|
|
||||||
};
|
#[allow(deprecated)]
|
||||||
|
pub use dispatching::repls::{commands_repl, commands_repl_with_listener};
|
||||||
|
|
||||||
pub mod dispatching;
|
pub mod dispatching;
|
||||||
pub mod error_handlers;
|
pub mod error_handlers;
|
||||||
|
|
|
@ -6,7 +6,8 @@ pub use crate::error_handlers::{LoggingErrorHandler, OnError};
|
||||||
pub use crate::respond;
|
pub use crate::respond;
|
||||||
|
|
||||||
pub use crate::dispatching::{
|
pub use crate::dispatching::{
|
||||||
dialogue::Dialogue, Dispatcher, HandlerExt as _, MessageFilterExt as _, UpdateFilterExt as _,
|
dialogue::Dialogue, repls::CommandRepl as _, Dispatcher, HandlerExt as _,
|
||||||
|
MessageFilterExt as _, UpdateFilterExt as _,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use teloxide_core::{
|
pub use teloxide_core::{
|
||||||
|
|
Loading…
Reference in a new issue