Merge branch 'dev' into const-must-use

This commit is contained in:
Sima Kinsart 2022-12-09 19:17:55 +06:00 committed by GitHub
commit bb6dd81f6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 215 additions and 124 deletions

View file

@ -157,6 +157,13 @@ jobs:
command: check command: check
args: --examples --features full args: --examples --features full
# TODO: prolly move it to a separate step?
- name: Check with no default features
uses: actions-rs/cargo@v1
with:
command: check
args: --no-default-features
clippy: clippy:
name: Run linter name: Run linter
runs-on: ubuntu-latest runs-on: ubuntu-latest

View file

@ -6,7 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## unreleased ## unreleased
## Removed ### Changed
- Updated `axum` to v0.6.0.
### Removed
- `rocksdb-storage` feature and associated items (See [PR #761](https://github.com/teloxide/teloxide/pull/761) for reasoning) [**BC**] - `rocksdb-storage` feature and associated items (See [PR #761](https://github.com/teloxide/teloxide/pull/761) for reasoning) [**BC**]
@ -16,7 +20,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The following functions were made `#[must_use]`: - The following functions were made `#[must_use]`:
- `DispatcherBuilder::{enable_ctrlc_handler, distribution_function}` - `DispatcherBuilder::{enable_ctrlc_handler, distribution_function}`
## 0.11.1 - 2022-10-31 ## 0.11.3 - 2022-11-28
### Fixed
- Add another missing feature gate for `dispatching::repls` import ([issue #770](https://github.com/teloxide/teloxide/issues/770))
## 0.11.2 - 2022-11-18
### Fixed
- Add missing feature gate for `dispatching::repls` import ([issue #770](https://github.com/teloxide/teloxide/issues/770))
## 0.11.1 - 2022-10-31 [yanked]
This release was yanked because it accidentally [breaks backwards compatibility](https://github.com/teloxide/teloxide/issues/770).
### Added ### Added

View file

@ -1,2 +1,13 @@
[workspace] [workspace]
members = ["crates/*"] members = ["crates/*"]
# The settings below will be applied to all crates in the workspace
[workspace.package]
# MSRV (minimal supported Rust version).
rust-version = "1.64"
edition = "2021"
license = "MIT"
homepage = "https://github.com/teloxide/teloxide"
repository = "https://github.com/teloxide/teloxide"

View file

@ -9,7 +9,7 @@ Note that the list of required changes is not fully exhaustive and it may lack s
If you are using rocksdb storage, you'll need to either write `Storage` impl yourself, or use a third party crate. If you are using rocksdb storage, you'll need to either write `Storage` impl yourself, or use a third party crate.
<!-- FIXME: add a link once there *is* a third party crate --> <!-- FIXME: add a link once there *is* a third party crate -->
## 0.11 -> 0.11.1 ## 0.11 -> 0.11.3
### teloxide ### teloxide

View file

@ -1,4 +1,4 @@
> [v0.11 -> v0.11.1 migration guide >>](MIGRATION_GUIDE.md#011---0111) > [v0.11 -> v0.11.3 migration guide >>](MIGRATION_GUIDE.md#011---0113)
<div align="center"> <div align="center">
<img src="./media/teloxide-logo.png" width="250"/> <img src="./media/teloxide-logo.png" width="250"/>

View file

@ -1,64 +1,20 @@
[package] [package]
name = "teloxide-core" name = "teloxide-core"
description = "Core part of the `teloxide` library - telegram bot API client"
version = "0.8.0" version = "0.8.0"
edition = "2021" description = "Core part of the `teloxide` library - telegram bot API client"
rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
license = "MIT"
repository = "https://github.com/teloxide/teloxide-core/"
homepage = "https://github.com/teloxide/teloxide-core/"
documentation = "https://docs.rs/teloxide-core/" documentation = "https://docs.rs/teloxide-core/"
readme = "README.md" readme = "README.md"
keywords = ["telegram", "bot", "tba"] keywords = ["teloxide", "telegram", "telegram-bot", "telegram-bot-api", "bot", "TBA"]
categories = ["api-bindings", "asynchronous"] categories = ["api-bindings", "asynchronous"]
exclude = [
".github/*",
"netlify.toml",
]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
futures = "0.3.5"
tokio = { version = "1.12.0", features = ["fs"] }
tokio-util = { version = "0.7.0", features = ["codec"] }
pin-project = "1.0.12"
bytes = "1.0.0"
reqwest = { version = "0.11.10", features = ["json", "stream", "multipart"], default-features = false }
url = { version = "2", features = ["serde"] }
log = "0.4"
serde = { version = "1.0.114", features = ["derive"] }
serde_json = "1.0.55"
serde_with_macros = "1.5.2"
uuid = { version = "1.1.0", features = ["v4"] } # for attaching input files
derive_more = "0.99.9"
mime = "0.3.16"
thiserror = "1.0.20"
once_cell = "1.5.0"
takecell = "0.1"
take_mut = "0.2"
rc-box = "1.1.1"
never = "0.1.0"
chrono = { version = "0.4.19", default-features = false }
either = "1.6.1"
bitflags = { version = "1.2" }
vecrem = { version = "0.1", optional = true }
[dev-dependencies]
pretty_env_logger = "0.4"
tokio = { version = "1.8.0", features = ["fs", "macros", "macros", "rt-multi-thread"] }
cool_asserts = "2.0.3"
xshell = "0.2"
ron = "0.7"
indexmap = { version = "1.9", features = ["serde-1"] }
aho-corasick = "0.7"
itertools = "0.10"
[features] [features]
default = ["native-tls"] default = ["native-tls"]
@ -90,6 +46,49 @@ auto_send = []
# All features except nightly and tls-related # All features except nightly and tls-related
full = ["throttle", "trace_adaptor", "erased", "cache_me", "auto_send"] full = ["throttle", "trace_adaptor", "erased", "cache_me", "auto_send"]
[dependencies]
futures = "0.3.5"
tokio = { version = "1.12.0", features = ["fs"] }
tokio-util = { version = "0.7.0", features = ["codec"] }
pin-project = "1.0.12"
bytes = "1.0.0"
reqwest = { version = "0.11.10", features = ["json", "stream", "multipart"], default-features = false }
url = { version = "2", features = ["serde"] }
log = "0.4"
serde = { version = "1.0.114", features = ["derive"] }
serde_json = "1.0.55"
serde_with_macros = "1.5.2"
uuid = { version = "1.1.0", features = ["v4"] } # for attaching input files
derive_more = "0.99.9"
mime = "0.3.16"
thiserror = "1.0.20"
once_cell = "1.5.0"
takecell = "0.1"
take_mut = "0.2"
rc-box = "1.1.1"
never = "0.1.0"
chrono = { version = "0.4.19", default-features = false }
either = "1.6.1"
bitflags = { version = "1.2" }
vecrem = { version = "0.1", optional = true }
[dev-dependencies]
pretty_env_logger = "0.4"
tokio = { version = "1.8.0", features = ["fs", "macros", "macros", "rt-multi-thread"] }
cool_asserts = "2.0.3"
xshell = "0.2"
ron = "0.7"
indexmap = { version = "1.9", features = ["serde-1"] }
aho-corasick = "0.7"
itertools = "0.10"
[package.metadata.docs.rs] [package.metadata.docs.rs]
features = ["full", "nightly", "tokio/macros", "tokio/rt-multi-thread"] features = ["full", "nightly", "tokio/macros", "tokio/rt-multi-thread"]
rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"] rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"]
@ -97,6 +96,7 @@ rustdoc-args = ["--cfg", "docsrs", "-Znormalize-docs"]
# https://github.com/rust-lang/rust/issues/88791 # https://github.com/rust-lang/rust/issues/88791
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"] cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
[[example]] [[example]]
name = "self_info" name = "self_info"
required-features = ["tokio/macros", "tokio/rt-multi-thread"] required-features = ["tokio/macros", "tokio/rt-multi-thread"]

View file

@ -90,8 +90,8 @@ use crate::{
/// ///
/// Because of this it's oftentimes more convinient to have a type alias: /// Because of this it's oftentimes more convinient to have a type alias:
/// ///
/// ```rust /// ```rust,no_run
/// # async { /// # #[cfg(feature = "throttle")] {
/// # use teloxide_core::{adaptors::{DefaultParseMode, Throttle}, requests::RequesterExt, types::ParseMode}; /// # use teloxide_core::{adaptors::{DefaultParseMode, Throttle}, requests::RequesterExt, types::ParseMode};
/// type Bot = DefaultParseMode<Throttle<teloxide_core::Bot>>; /// type Bot = DefaultParseMode<Throttle<teloxide_core::Bot>>;
/// ///

View file

@ -2,14 +2,22 @@
name = "teloxide-macros" name = "teloxide-macros"
version = "0.7.0" version = "0.7.0"
description = "The teloxide's procedural macros" description = "The teloxide's procedural macros"
license = "MIT"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
documentation = "https://docs.rs/teloxide-core/"
# FIXME: add a simple readme for teloxide-macros
#readme = "README.md"
[lib] [lib]
proc-macro = true proc-macro = true
[dependencies] [dependencies]
quote = "1.0.7" quote = "1.0.7"
proc-macro2 = "1.0.19" proc-macro2 = "1.0.19"

View file

@ -1,15 +1,20 @@
[package] [package]
name = "teloxide" name = "teloxide"
version = "0.11.1" version = "0.11.3"
edition = "2021"
description = "An elegant Telegram bots framework for Rust" description = "An elegant Telegram bots framework for Rust"
repository = "https://github.com/teloxide/teloxide"
rust-version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
documentation = "https://docs.rs/teloxide/" documentation = "https://docs.rs/teloxide/"
readme = "../../README.md" readme = "../../README.md"
keywords = ["teloxide", "telegram", "telegram-bot", "telegram-bot-api"]
keywords = ["teloxide", "telegram", "telegram-bot", "telegram-bot-api", "bot", "TBA"]
categories = ["web-programming", "api-bindings", "asynchronous"] categories = ["web-programming", "api-bindings", "asynchronous"]
license = "MIT"
exclude = ["media", "README.md"]
[features] [features]
default = ["native-tls", "ctrlc_handler", "teloxide-core/default", "auto-send"] default = ["native-tls", "ctrlc_handler", "teloxide-core/default", "auto-send"]
@ -56,6 +61,7 @@ full = [
"erased", "erased",
] ]
[dependencies] [dependencies]
teloxide-core = { version = "0.8.0", default-features = false } teloxide-core = { version = "0.8.0", default-features = false }
teloxide-macros = { version = "0.7.0", optional = true } teloxide-macros = { version = "0.7.0", optional = true }
@ -94,11 +100,12 @@ sqlx = { version = "0.6", optional = true, default-features = false, features =
redis = { version = "0.21", features = ["tokio-comp"], optional = true } redis = { version = "0.21", features = ["tokio-comp"], optional = true }
serde_cbor = { version = "0.11", optional = true } serde_cbor = { version = "0.11", optional = true }
bincode = { version = "1.3", optional = true } bincode = { version = "1.3", optional = true }
axum = { version = "0.5.13", optional = true } axum = { version = "0.6.0", optional = true }
tower = { version = "0.4.12", optional = true } tower = { version = "0.4.12", optional = true }
tower-http = { version = "0.3.4", features = ["trace"], optional = true } tower-http = { version = "0.3.4", features = ["trace"], optional = true }
rand = { version = "0.8.5", optional = true } rand = { version = "0.8.5", optional = true }
[dev-dependencies] [dev-dependencies]
rand = "0.8.3" rand = "0.8.3"
pretty_env_logger = "0.4.0" pretty_env_logger = "0.4.0"
@ -109,6 +116,7 @@ reqwest = "0.11.11"
chrono = "0.4" chrono = "0.4"
tokio-stream = "0.1" tokio-stream = "0.1"
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
# FIXME: Add back "-Znormalize-docs" when https://github.com/rust-lang/rust/issues/93703 is fixed # FIXME: Add back "-Znormalize-docs" when https://github.com/rust-lang/rust/issues/93703 is fixed
@ -116,6 +124,7 @@ rustdoc-args = ["--cfg", "docsrs"]
rustc-args = ["--cfg", "dep_docsrs"] rustc-args = ["--cfg", "dep_docsrs"]
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"] cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"]
[[test]] [[test]]
name = "redis" name = "redis"
path = "tests/redis.rs" path = "tests/redis.rs"
@ -126,42 +135,51 @@ name = "sqlite"
path = "tests/sqlite.rs" path = "tests/sqlite.rs"
required-features = ["sqlite-storage", "cbor-serializer", "bincode-serializer"] required-features = ["sqlite-storage", "cbor-serializer", "bincode-serializer"]
[[example]] [[example]]
name = "dialogue" name = "admin"
required-features = ["macros"] required-features = ["macros", "ctrlc_handler"]
[[example]]
name = "buttons"
required-features = ["macros", "ctrlc_handler"]
[[example]] [[example]]
name = "command" name = "command"
required-features = ["macros"] required-features = ["macros", "ctrlc_handler"]
[[example]] [[example]]
name = "db_remember" name = "db_remember"
required-features = ["sqlite-storage", "redis-storage", "bincode-serializer", "macros"] required-features = ["sqlite-storage", "redis-storage", "bincode-serializer", "macros"]
[[example]] [[example]]
name = "inline" name = "dialogue"
required-features = ["macros"] required-features = ["macros", "ctrlc_handler"]
[[example]]
name = "buttons"
required-features = ["macros"]
[[example]]
name = "admin"
required-features = ["macros"]
[[example]] [[example]]
name = "dispatching_features" name = "dispatching_features"
required-features = ["macros"] required-features = ["macros", "ctrlc_handler"]
[[example]]
name = "ngrok_ping_pong"
required-features = ["webhooks-axum"]
[[example]] [[example]]
name = "heroku_ping_pong" name = "heroku_ping_pong"
required-features = ["webhooks-axum"] required-features = ["webhooks-axum", "ctrlc_handler"]
[[example]]
name = "inline"
required-features = ["macros", "ctrlc_handler"]
[[example]]
name = "ngrok_ping_pong"
required-features = ["webhooks-axum", "ctrlc_handler"]
[[example]] [[example]]
name = "purchase" name = "purchase"
required-features = ["macros"] required-features = ["macros", "ctrlc_handler"]
[[example]]
name = "shared_state"
required-features = ["ctrlc_handler"]
[[example]]
name = "throw_dice"
required-features = ["ctrlc_handler"]

View file

@ -1,6 +1,6 @@
//! An update dispatching model based on [`dptree`]. //! An update dispatching model based on [`dptree`].
//! //!
//! In teloxide, update dispatching is declarative: it takes the form of a //! In `teloxide`, update dispatching is declarative: it takes the form of a
//! [chain of responsibility] pattern enriched with a number of combinator //! [chain of responsibility] pattern enriched with a number of combinator
//! functions, which together form an instance of the [`dptree::Handler`] type. //! functions, which together form an instance of the [`dptree::Handler`] type.
//! //!
@ -23,6 +23,7 @@
//! `/start` or `/help`: //! `/start` or `/help`:
//! //!
//! ```no_run //! ```no_run
//! # #[cfg(feature = "macros")] {
//! # use teloxide::utils::command::BotCommands; //! # use teloxide::utils::command::BotCommands;
//! #[derive(BotCommands, Clone)] //! #[derive(BotCommands, Clone)]
//! #[command(rename_rule = "lowercase", description = "These commands are supported:")] //! #[command(rename_rule = "lowercase", description = "These commands are supported:")]
@ -34,6 +35,7 @@
//! #[command(description = "cancel the purchase procedure.")] //! #[command(description = "cancel the purchase procedure.")]
//! Cancel, //! Cancel,
//! } //! }
//! # }
//! ``` //! ```
//! //!
//! Now the key question: how to elegantly dispatch on different combinations of //! Now the key question: how to elegantly dispatch on different combinations of
@ -43,6 +45,7 @@
//! solution is to use [`dptree`]: //! solution is to use [`dptree`]:
//! //!
//! ```no_run //! ```no_run
//! # #[cfg(feature = "macros")] {
//! # // That's a lot of context needed to compile this, oof //! # // That's a lot of context needed to compile this, oof
//! # use teloxide::dispatching::{UpdateHandler, UpdateFilterExt, dialogue, dialogue::InMemStorage}; //! # use teloxide::dispatching::{UpdateHandler, UpdateFilterExt, dialogue, dialogue::InMemStorage};
//! # use teloxide::utils::command::BotCommands; //! # use teloxide::utils::command::BotCommands;
@ -81,6 +84,7 @@
//! .branch(message_handler) //! .branch(message_handler)
//! .branch(callback_query_handler) //! .branch(callback_query_handler)
//! } //! }
//! # }
//! ``` //! ```
//! //!
//! The overall logic should be clear. Throughout the above example, we use //! The overall logic should be clear. Throughout the above example, we use
@ -149,6 +153,7 @@
//! Inside `main`, we plug the schema into [`Dispatcher`] like this: //! Inside `main`, we plug the schema into [`Dispatcher`] like this:
//! //!
//! ```no_run //! ```no_run
//! # #[cfg(feature = "ctrlc_handler")] {
//! # use teloxide::Bot; //! # use teloxide::Bot;
//! # use teloxide::requests::RequesterExt; //! # use teloxide::requests::RequesterExt;
//! # use teloxide::dispatching::{Dispatcher, dialogue::InMemStorage}; //! # use teloxide::dispatching::{Dispatcher, dialogue::InMemStorage};
@ -165,6 +170,7 @@
//! .dispatch() //! .dispatch()
//! .await; //! .await;
//! } //! }
//! # }
//! ``` //! ```
//! //!
//! In a call to [`DispatcherBuilder::dependencies`], we specify a list of //! In a call to [`DispatcherBuilder::dependencies`], we specify a list of

View file

@ -146,6 +146,9 @@ where
ctrlc_handler, ctrlc_handler,
} = self; } = self;
// If the `ctrlc_handler` feature is not enabled, don't emit a warning.
let _ = ctrlc_handler;
let dp = Dispatcher { let dp = Dispatcher {
bot, bot,
dependencies, dependencies,

View file

@ -77,14 +77,15 @@ impl EventKind for Kind {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[cfg(feature = "macros")]
use crate::{ use crate::{
self as teloxide, // fixup for the `BotCommands` macro
dispatching::{HandlerExt, UpdateFilterExt}, dispatching::{HandlerExt, UpdateFilterExt},
types::{AllowedUpdate::*, Update}, types::{AllowedUpdate::*, Update},
utils::command::BotCommands, utils::command::BotCommands,
}; };
use crate as teloxide; // fixup for the `BotCommands` macro #[cfg(feature = "macros")]
#[derive(BotCommands, Clone)] #[derive(BotCommands, Clone)]
#[command(rename_rule = "lowercase")] #[command(rename_rule = "lowercase")]
enum Cmd { enum Cmd {
@ -93,6 +94,7 @@ mod tests {
// <https://github.com/teloxide/teloxide/discussions/648> // <https://github.com/teloxide/teloxide/discussions/648>
#[test] #[test]
#[cfg(feature = "macros")]
fn discussion_648() { fn discussion_648() {
let h = let h =
dptree::entry().branch(Update::filter_my_chat_member().endpoint(|| async {})).branch( dptree::entry().branch(Update::filter_my_chat_member().endpoint(|| async {})).branch(
@ -108,4 +110,11 @@ mod tests {
assert_eq!(v, [Message, MyChatMember]) assert_eq!(v, [Message, MyChatMember])
} }
#[test]
#[ignore = "this test requires `macros` feature"]
#[cfg(not(feature = "macros"))]
fn discussion_648() {
panic!("this test requires `macros` feature")
}
} }

View file

@ -1,14 +1,16 @@
use std::{convert::Infallible, future::Future, pin::Pin}; use std::{convert::Infallible, future::Future, pin::Pin};
use axum::{ use axum::{
extract::{FromRequest, RequestParts}, extract::{FromRequestParts, State},
http::status::StatusCode, http::{request::Parts, status::StatusCode},
}; };
use tokio::sync::mpsc;
use crate::{ use crate::{
dispatching::update_listeners::{webhooks::Options, UpdateListener}, dispatching::update_listeners::{webhooks::Options, UpdateListener},
requests::Requester, requests::Requester,
stop::StopFlag, stop::StopFlag,
types::Update,
}; };
/// Webhook implementation based on the [mod@axum] framework. /// Webhook implementation based on the [mod@axum] framework.
@ -156,25 +158,17 @@ pub fn axum_no_setup(
use crate::{ use crate::{
dispatching::update_listeners::{self, webhooks::tuple_first_mut}, dispatching::update_listeners::{self, webhooks::tuple_first_mut},
stop::{mk_stop_token, StopToken}, stop::{mk_stop_token, StopToken},
types::Update,
}; };
use axum::{extract::Extension, response::IntoResponse, routing::post}; use axum::{response::IntoResponse, routing::post};
use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream; use tokio_stream::wrappers::UnboundedReceiverStream;
use tower::ServiceBuilder;
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
type Sender = mpsc::UnboundedSender<Result<Update, std::convert::Infallible>>; let (tx, rx): (UpdateSender, _) = mpsc::unbounded_channel();
type CSender = ClosableSender<Result<Update, std::convert::Infallible>>;
let (tx, rx): (Sender, _) = mpsc::unbounded_channel();
async fn telegram_request( async fn telegram_request(
input: String, State(WebhookState { secret, flag, mut tx }): State<WebhookState>,
secret_header: XTelegramBotApiSecretToken, secret_header: XTelegramBotApiSecretToken,
secret: Extension<Option<String>>, input: String,
tx: Extension<CSender>,
flag: Extension<StopFlag>,
) -> impl IntoResponse { ) -> impl IntoResponse {
// FIXME: use constant time comparison here // FIXME: use constant time comparison here
if secret_header.0.as_deref() != secret.as_deref().map(str::as_bytes) { if secret_header.0.as_deref() != secret.as_deref().map(str::as_bytes) {
@ -186,7 +180,7 @@ pub fn axum_no_setup(
// Do not process updates after `.stop()` is called even if the server is still // Do not process updates after `.stop()` is called even if the server is still
// running (useful for when you need to stop the bot but can't stop the server). // running (useful for when you need to stop the bot but can't stop the server).
_ if flag.is_stopped() => { _ if flag.is_stopped() => {
{ tx.0 }.close(); tx.close();
return StatusCode::SERVICE_UNAVAILABLE; return StatusCode::SERVICE_UNAVAILABLE;
} }
Some(tx) => tx, Some(tx) => tx,
@ -212,14 +206,14 @@ pub fn axum_no_setup(
let (stop_token, stop_flag) = mk_stop_token(); let (stop_token, stop_flag) = mk_stop_token();
let app = axum::Router::new().route(options.url.path(), post(telegram_request)).layer( let app = axum::Router::new()
ServiceBuilder::new() .route(options.url.path(), post(telegram_request))
.layer(TraceLayer::new_for_http()) .layer(TraceLayer::new_for_http())
.layer(Extension(ClosableSender::new(tx))) .with_state(WebhookState {
.layer(Extension(stop_flag.clone())) tx: ClosableSender::new(tx),
.layer(Extension(options.secret_token)) flag: stop_flag.clone(),
.into_inner(), secret: options.secret_token,
); });
let stream = UnboundedReceiverStream::new(rx); let stream = UnboundedReceiverStream::new(rx);
@ -233,9 +227,19 @@ pub fn axum_no_setup(
(listener, stop_flag, app) (listener, stop_flag, app)
} }
type UpdateSender = mpsc::UnboundedSender<Result<Update, std::convert::Infallible>>;
type UpdateCSender = ClosableSender<Result<Update, std::convert::Infallible>>;
#[derive(Clone)]
struct WebhookState {
tx: UpdateCSender,
flag: StopFlag,
secret: Option<String>,
}
/// A terrible workaround to drop axum extension /// A terrible workaround to drop axum extension
struct ClosableSender<T> { struct ClosableSender<T> {
origin: std::sync::Arc<std::sync::RwLock<Option<tokio::sync::mpsc::UnboundedSender<T>>>>, origin: std::sync::Arc<std::sync::RwLock<Option<mpsc::UnboundedSender<T>>>>,
} }
impl<T> Clone for ClosableSender<T> { impl<T> Clone for ClosableSender<T> {
@ -245,11 +249,11 @@ impl<T> Clone for ClosableSender<T> {
} }
impl<T> ClosableSender<T> { impl<T> ClosableSender<T> {
fn new(sender: tokio::sync::mpsc::UnboundedSender<T>) -> Self { fn new(sender: mpsc::UnboundedSender<T>) -> Self {
Self { origin: std::sync::Arc::new(std::sync::RwLock::new(Some(sender))) } Self { origin: std::sync::Arc::new(std::sync::RwLock::new(Some(sender))) }
} }
fn get(&self) -> Option<tokio::sync::mpsc::UnboundedSender<T>> { fn get(&self) -> Option<mpsc::UnboundedSender<T>> {
self.origin.read().unwrap().clone() self.origin.read().unwrap().clone()
} }
@ -260,20 +264,22 @@ impl<T> ClosableSender<T> {
struct XTelegramBotApiSecretToken(Option<Vec<u8>>); struct XTelegramBotApiSecretToken(Option<Vec<u8>>);
impl<B> FromRequest<B> for XTelegramBotApiSecretToken { impl<S> FromRequestParts<S> for XTelegramBotApiSecretToken {
type Rejection = StatusCode; type Rejection = StatusCode;
fn from_request<'l0, 'at>( fn from_request_parts<'l0, 'l1, 'at>(
req: &'l0 mut RequestParts<B>, req: &'l0 mut Parts,
_state: &'l1 S,
) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'at>> ) -> Pin<Box<dyn Future<Output = Result<Self, Self::Rejection>> + Send + 'at>>
where where
'l0: 'at, 'l0: 'at,
'l1: 'at,
Self: 'at, Self: 'at,
{ {
use crate::dispatching::update_listeners::webhooks::check_secret; use crate::dispatching::update_listeners::webhooks::check_secret;
let res = req let res = req
.headers_mut() .headers
.remove("x-telegram-bot-api-secret-token") .remove("x-telegram-bot-api-secret-token")
.map(|header| { .map(|header| {
check_secret(header.as_bytes()) check_secret(header.as_bytes())

View file

@ -6,8 +6,10 @@
//! //!
//! [[`examples/throw_dice.rs`](https://github.com/teloxide/teloxide/blob/master/examples/throw_dice.rs)] //! [[`examples/throw_dice.rs`](https://github.com/teloxide/teloxide/blob/master/examples/throw_dice.rs)]
//! ```no_run //! ```no_run
//! # #[cfg(feature = "ctrlc_handler")]
//! use teloxide::prelude::*; //! use teloxide::prelude::*;
//! //!
//! # #[cfg(feature = "ctrlc_handler")]
//! # #[tokio::main] //! # #[tokio::main]
//! # async fn main() { //! # async fn main() {
//! pretty_env_logger::init(); //! pretty_env_logger::init();
@ -20,7 +22,7 @@
//! Ok(()) //! Ok(())
//! }) //! })
//! .await; //! .await;
//! # } //! # } #[cfg(not(feature = "ctrlc_handler"))] fn main(){}
//! ``` //! ```
//! //!
//! <div align="center"> //! <div align="center">
@ -60,6 +62,7 @@
#[cfg(feature = "ctrlc_handler")] #[cfg(feature = "ctrlc_handler")]
pub use dispatching::repls::{repl, repl_with_listener}; pub use dispatching::repls::{repl, repl_with_listener};
#[cfg(feature = "ctrlc_handler")]
#[allow(deprecated)] #[allow(deprecated)]
pub use dispatching::repls::{commands_repl, commands_repl_with_listener}; pub use dispatching::repls::{commands_repl, commands_repl_with_listener};

View file

@ -6,10 +6,12 @@ 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, repls::CommandReplExt as _, Dispatcher, HandlerExt as _, dialogue::Dialogue, Dispatcher, HandlerExt as _, MessageFilterExt as _, UpdateFilterExt as _,
MessageFilterExt as _, UpdateFilterExt as _,
}; };
#[cfg(feature = "ctrlc_handler")]
pub use crate::dispatching::repls::CommandReplExt as _;
pub use teloxide_core::{ pub use teloxide_core::{
requests::ResponseResult, requests::ResponseResult,
types::{ types::{