mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 06:25:10 +01:00
Merge pull request #712 from teloxide/repl_docs_upd
Update docs of REPLs
Former-commit-id: f52d11d246
This commit is contained in:
commit
cbd8978e65
6 changed files with 198 additions and 83 deletions
|
@ -1,4 +1,12 @@
|
||||||
//! REPLs for dispatching updates.
|
//! [REPL]s for dispatching updates.
|
||||||
|
//!
|
||||||
|
//! This module provides utilities for easy update handling. They accept a
|
||||||
|
//! single "handler" function that processes all updates of a certain kind. Note
|
||||||
|
//! that REPLs are meant to be used for simple scenarios, such as prototyping,
|
||||||
|
//! inasmuch they lack configuration and some [advanced features].
|
||||||
|
//!
|
||||||
|
//! [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
||||||
|
//! [advanced features]: crate::dispatching#dispatching-or-repls
|
||||||
|
|
||||||
mod commands_repl;
|
mod commands_repl;
|
||||||
mod repl;
|
mod repl;
|
||||||
|
|
2
src/dispatching/repls/caution.md
Normal file
2
src/dispatching/repls/caution.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
**DO NOT** use this function together with [`Dispatcher`] and other REPLs,
|
||||||
|
because Telegram disallow multiple requests at the same time from the same bot.
|
|
@ -3,44 +3,68 @@ use crate::{
|
||||||
update_listeners, update_listeners::UpdateListener, HandlerExt, UpdateFilterExt,
|
update_listeners, update_listeners::UpdateListener, HandlerExt, UpdateFilterExt,
|
||||||
},
|
},
|
||||||
error_handlers::LoggingErrorHandler,
|
error_handlers::LoggingErrorHandler,
|
||||||
|
requests::{Requester, ResponseResult},
|
||||||
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};
|
||||||
use teloxide_core::requests::Requester;
|
|
||||||
|
|
||||||
/// A [REPL] for commands.
|
/// A [REPL] for commands.
|
||||||
|
//
|
||||||
///
|
///
|
||||||
/// All errors from an update listener and handler will be logged.
|
//
|
||||||
///
|
#[doc = include_str!("preamble.md")]
|
||||||
/// 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?"](dispatching/index.html#dispatching-or-repls)
|
|
||||||
///
|
|
||||||
/// ## Caution
|
|
||||||
///
|
|
||||||
/// **DO NOT** use this function together with [`Dispatcher`] and other REPLs,
|
|
||||||
/// because Telegram disallow multiple requests at the same time from the same
|
|
||||||
/// bot.
|
|
||||||
///
|
|
||||||
/// ## Dependency requirements
|
|
||||||
///
|
|
||||||
/// - Those of [`HandlerExt::filter_command`]
|
|
||||||
///
|
///
|
||||||
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
///
|
||||||
|
/// ## Signature
|
||||||
|
///
|
||||||
|
/// Don't be scared by many trait bounds in the signature, 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. `cmd` is a type hint for your command enumeration
|
||||||
|
/// `MyCommand`: just write `MyCommand::ty()`. Note that `MyCommand` must
|
||||||
|
/// implement the [`BotCommands`] trait, typically via
|
||||||
|
/// `#[derive(BotCommands)]`.
|
||||||
|
///
|
||||||
|
/// 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")]
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
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
|
||||||
Cmd: BotCommands + 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,
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static,
|
||||||
|
Cmd: BotCommands + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let cloned_bot = bot.clone();
|
let cloned_bot = bot.clone();
|
||||||
|
|
||||||
|
@ -53,45 +77,72 @@ where
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like [`commands_repl`], but with a custom [`UpdateListener`].
|
/// A [REPL] for commands, with a custom [`UpdateListener`].
|
||||||
|
//
|
||||||
///
|
///
|
||||||
/// All errors from an update listener and handler will be logged.
|
//
|
||||||
|
#[doc = include_str!("preamble.md")]
|
||||||
///
|
///
|
||||||
/// REPLs are meant only for simple bots and rapid prototyping. If you need to
|
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
||||||
/// supply dependencies or describe more complex dispatch logic, please use
|
|
||||||
/// [`Dispatcher`].
|
|
||||||
///
|
///
|
||||||
/// See also: ["Dispatching or
|
/// ## Signature
|
||||||
/// REPLs?"](dispatching/index.html#dispatching-or-repls)
|
///
|
||||||
|
/// Don't be scared by many trait bounds in the signature, 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`].
|
||||||
|
/// 4. `cmd` is a type hint for your command enumeration `MyCommand`: just
|
||||||
|
/// write `MyCommand::ty()`. Note that `MyCommand` must implement the
|
||||||
|
/// [`BotCommands`] trait, typically via `#[derive(BotCommands)]`.
|
||||||
|
///
|
||||||
|
/// 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
|
/// ## Caution
|
||||||
|
//
|
||||||
|
#[doc = include_str!("caution.md")]
|
||||||
///
|
///
|
||||||
/// **DO NOT** use this function together with [`Dispatcher`] and other REPLs,
|
|
||||||
/// because Telegram disallow multiple requests at the same time from the same
|
|
||||||
/// bot.
|
|
||||||
///
|
|
||||||
/// ## Dependency requirements
|
|
||||||
///
|
|
||||||
/// - Those of [`HandlerExt::filter_command`]
|
|
||||||
///
|
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
|
||||||
/// [`commands_repl`]: crate::dispatching::repls::commands_repl()
|
|
||||||
/// [`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, 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<(), RequestError>, Args> + Send + Sync + 'static,
|
H: Injectable<DependencyMap, ResponseResult<()>, 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,
|
||||||
{
|
{
|
||||||
use crate::dispatching::Dispatcher;
|
use crate::dispatching::Dispatcher;
|
||||||
|
|
||||||
|
let _ = cmd;
|
||||||
|
|
||||||
// Other update types are of no interest to use since this REPL is only for
|
// Other update types are of no interest to use since this REPL is only for
|
||||||
// commands. See <https://github.com/teloxide/teloxide/issues/557>.
|
// commands. See <https://github.com/teloxide/teloxide/issues/557>.
|
||||||
let ignore_update = |_upd| Box::pin(async {});
|
let ignore_update = |_upd| Box::pin(async {});
|
||||||
|
|
7
src/dispatching/repls/preamble.md
Normal file
7
src/dispatching/repls/preamble.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
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?"](dispatching/index.html#dispatching-or-repls).
|
||||||
|
|
||||||
|
[`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
|
|
||||||
|
All errors from the handler and update listener will be logged.
|
|
@ -1,70 +1,113 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
dispatching::{update_listeners, update_listeners::UpdateListener, UpdateFilterExt},
|
dispatching::{update_listeners, update_listeners::UpdateListener, UpdateFilterExt},
|
||||||
error_handlers::LoggingErrorHandler,
|
error_handlers::LoggingErrorHandler,
|
||||||
|
requests::{Requester, ResponseResult},
|
||||||
types::Update,
|
types::Update,
|
||||||
RequestError,
|
|
||||||
};
|
};
|
||||||
use dptree::di::{DependencyMap, Injectable};
|
use dptree::di::{DependencyMap, Injectable};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use teloxide_core::requests::Requester;
|
|
||||||
|
|
||||||
/// A [REPL] for messages.
|
/// A [REPL] for messages.
|
||||||
|
//
|
||||||
///
|
///
|
||||||
/// All errors from an update listener and a handler will be logged.
|
//
|
||||||
///
|
#[doc = include_str!("preamble.md")]
|
||||||
/// 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?"](dispatching/index.html#dispatching-or-repls)
|
|
||||||
///
|
|
||||||
/// ## Caution
|
|
||||||
///
|
|
||||||
/// **DO NOT** use this function together with [`Dispatcher`] and other REPLs,
|
|
||||||
/// because Telegram disallow multiple requests at the same time from the same
|
|
||||||
/// bot.
|
|
||||||
///
|
///
|
||||||
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
///
|
||||||
|
/// ## Signature
|
||||||
|
///
|
||||||
|
/// Don't be scared by many trait bounds in the signature, 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`].
|
||||||
|
///
|
||||||
|
/// ## Handler arguments
|
||||||
|
///
|
||||||
|
/// Teloxide provides the following types to the `handler`:
|
||||||
|
/// - [`Message`]
|
||||||
|
/// - `R` (type of the `bot`)
|
||||||
|
/// - [`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 message without [`Me`].
|
||||||
|
///
|
||||||
|
/// [`Me`]: crate::types::Me
|
||||||
|
/// [`Message`]: crate::types::Message
|
||||||
|
///
|
||||||
|
/// ## Stopping
|
||||||
|
//
|
||||||
|
#[doc = include_str!("stopping.md")]
|
||||||
|
///
|
||||||
|
/// ## Caution
|
||||||
|
//
|
||||||
|
#[doc = include_str!("caution.md")]
|
||||||
|
///
|
||||||
#[cfg(feature = "ctrlc_handler")]
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
pub async fn repl<R, H, Args>(bot: R, handler: H)
|
pub async fn repl<R, H, Args>(bot: R, handler: H)
|
||||||
where
|
where
|
||||||
H: Injectable<DependencyMap, Result<(), RequestError>, Args> + 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,
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let cloned_bot = bot.clone();
|
let cloned_bot = bot.clone();
|
||||||
repl_with_listener(bot, handler, update_listeners::polling_default(cloned_bot).await).await;
|
repl_with_listener(bot, handler, update_listeners::polling_default(cloned_bot).await).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like [`repl`], but with a custom [`UpdateListener`].
|
/// A [REPL] for messages, with a custom [`UpdateListener`].
|
||||||
|
//
|
||||||
///
|
///
|
||||||
/// All errors from an update listener and handler will be logged.
|
//
|
||||||
|
#[doc = include_str!("preamble.md")]
|
||||||
///
|
///
|
||||||
/// REPLs are meant only for simple bots and rapid prototyping. If you need to
|
/// [REPL]: https://en.wikipedia.org/wiki/Read-eval-print_loop
|
||||||
/// supply dependencies or describe more complex dispatch logic, please use
|
|
||||||
/// [`Dispatcher`].
|
|
||||||
///
|
|
||||||
/// See also: ["Dispatching or
|
|
||||||
/// REPLs?"](dispatching/index.html#dispatching-or-repls)
|
|
||||||
///
|
|
||||||
/// # Caution
|
|
||||||
///
|
|
||||||
/// **DO NOT** use this function together with [`Dispatcher`] and other REPLs,
|
|
||||||
/// because Telegram disallow multiple requests at the same time from the same
|
|
||||||
/// bot.
|
|
||||||
///
|
|
||||||
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
|
||||||
/// [`repl`]: crate::dispatching::repls::repl()
|
|
||||||
/// [`UpdateListener`]: crate::dispatching::update_listeners::UpdateListener
|
/// [`UpdateListener`]: crate::dispatching::update_listeners::UpdateListener
|
||||||
|
///
|
||||||
|
/// ## Signature
|
||||||
|
///
|
||||||
|
/// Don't be scared by many trait bounds in the signature, 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`].
|
||||||
|
///
|
||||||
|
/// ## Handler arguments
|
||||||
|
///
|
||||||
|
/// Teloxide provides the following types to the `handler`:
|
||||||
|
/// - [`Message`]
|
||||||
|
/// - `R` (type of the `bot`)
|
||||||
|
/// - [`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 message without [`Me`].
|
||||||
|
///
|
||||||
|
/// [`Me`]: crate::types::Me
|
||||||
|
/// [`Message`]: crate::types::Message
|
||||||
|
///
|
||||||
|
/// ## Stopping
|
||||||
|
//
|
||||||
|
#[doc = include_str!("stopping.md")]
|
||||||
|
///
|
||||||
|
/// ## Caution
|
||||||
|
//
|
||||||
|
#[doc = include_str!("caution.md")]
|
||||||
|
///
|
||||||
#[cfg(feature = "ctrlc_handler")]
|
#[cfg(feature = "ctrlc_handler")]
|
||||||
pub async fn repl_with_listener<'a, R, H, L, Args>(bot: R, handler: H, listener: L)
|
pub async fn repl_with_listener<R, H, L, Args>(bot: R, handler: H, listener: L)
|
||||||
where
|
where
|
||||||
H: Injectable<DependencyMap, Result<(), RequestError>, Args> + Send + Sync + 'static,
|
|
||||||
L: UpdateListener + Send + 'a,
|
|
||||||
L::Err: Debug,
|
|
||||||
R: Requester + Clone + Send + Sync + 'static,
|
R: Requester + Clone + Send + Sync + 'static,
|
||||||
|
H: Injectable<DependencyMap, ResponseResult<()>, Args> + Send + Sync + 'static,
|
||||||
|
L: UpdateListener + Send,
|
||||||
|
L::Err: Debug,
|
||||||
{
|
{
|
||||||
use crate::dispatching::Dispatcher;
|
use crate::dispatching::Dispatcher;
|
||||||
|
|
||||||
|
|
4
src/dispatching/repls/stopping.md
Normal file
4
src/dispatching/repls/stopping.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
To stop a REPL, simply press `Ctrl`+`C` in the terminal where you run the program.
|
||||||
|
Note that graceful shutdown may take some time (we plan to improve this, see [#711]).
|
||||||
|
|
||||||
|
[#711]: https://github.com/teloxide/teloxide/issues/711
|
Loading…
Reference in a new issue