From 2df66b62b786c038b930a57213a8545642df4a74 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 14:20:57 +0400 Subject: [PATCH 01/13] Update MSRV/toolchain versions --- .github/workflows/ci.yml | 42 ++++++---------------------------------- rust-toolchain.toml | 2 +- 2 files changed, 7 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 589bb662..5143bb29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,17 +17,12 @@ env: CARGO_NET_RETRY: 10 RUSTUP_MAX_RETRIES: 10 - rust_nightly: nightly-2022-01-17 + rust_nightly: nightly-2022-09-23 # When updating this, also update: # - README.md # - src/lib.rs # - down below in a matrix - rust_msrv: 1.58.0 - # When updating this, also update: - # - down below in a matrix - # - # This is needed because some of our tests can't run on MSRV. - rust_msrv_dev: 1.59.0 + rust_msrv: 1.64.0 CI: 1 @@ -43,7 +38,6 @@ jobs: - check-examples - clippy - doc - - msrv steps: - run: exit 0 @@ -82,7 +76,7 @@ jobs: - stable - beta - nightly - - msrv_dev + - msrv include: - rust: stable @@ -92,10 +86,10 @@ jobs: toolchain: beta features: "--features full" - rust: nightly - toolchain: nightly-2022-01-17 + toolchain: nightly-2022-09-23 features: "--all-features" - - rust: msrv_dev - toolchain: 1.59.0 + - rust: msrv + toolchain: 1.64.0 features: "--features full" steps: @@ -194,27 +188,3 @@ jobs: uses: actions-rs/cargo@v1 with: command: docs # from .cargo/config.toml - - msrv: - name: minimal supported rust version - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Rust ${{ env.rust_msrv }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ env.rust_msrv }} - override: true - - - name: Cache Dependencies - uses: Swatinem/rust-cache@v1 - - - name: Check - uses: actions-rs/cargo@v1 - with: - command: check - args: --verbose --features full diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 66a1979e..b4990f3d 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2022-01-17" +channel = "nightly-2022-09-23" components = ["rustfmt", "clippy"] profile = "minimal" From fe88ba29494b183d3b2d60bbbba5b181abee1486 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 17:33:22 +0400 Subject: [PATCH 02/13] Use `IntoFuture` for requests --- src/adaptors/auto_send.rs | 117 +++++-------------------------- src/adaptors/cache_me.rs | 10 +++ src/adaptors/erased.rs | 18 ++++- src/adaptors/throttle/request.rs | 21 +++++- src/adaptors/trace.rs | 17 ++++- src/requests/json.rs | 16 +++++ src/requests/multipart.rs | 16 +++++ src/requests/request.rs | 59 ++++++++-------- src/requests/requester.rs | 42 +++++------ 9 files changed, 161 insertions(+), 155 deletions(-) diff --git a/src/adaptors/auto_send.rs b/src/adaptors/auto_send.rs index e10f763f..5c01f081 100644 --- a/src/adaptors/auto_send.rs +++ b/src/adaptors/auto_send.rs @@ -1,10 +1,5 @@ -use std::{ - future::Future, - pin::Pin, - task::{Context, Poll}, -}; +use std::future::IntoFuture; -use futures::future::FusedFuture; use url::Url; use crate::{ @@ -192,33 +187,17 @@ download_forward! { } #[must_use = "Futures are lazy and do nothing unless polled or awaited"] -#[pin_project::pin_project] -pub struct AutoRequest(#[pin] Inner); +pub struct AutoRequest(R); impl AutoRequest where R: Request, { pub fn new(inner: R) -> Self { - Self(Inner::Request(inner)) + Self(inner) } } -/// Data of the `AutoRequest` used to not expose variants (I wish there were -/// private enum variants). -#[pin_project::pin_project(project = InnerProj, project_replace = InnerRepl)] -enum Inner { - /// An unsent modifiable request. - Request(R), - /// A sent request. - Future(#[pin] R::Send), - /// Done state. Set after `R::Send::poll` returned `Ready(_)`. - /// - /// Also used as a temporary replacement to turn pinned `Request(req)` - /// into `Future(req.send())` in `AutoRequest::poll`. - Done, -} - impl Request for AutoRequest where R: Request, @@ -228,19 +207,20 @@ where type SendRef = R::SendRef; fn send(self) -> Self::Send { - match self.0 { - Inner::Request(req) => req.send(), - Inner::Future(fut) => fut, - Inner::Done => done_unreachable(), - } + self.0.send() } fn send_ref(&self) -> Self::SendRef { - match &self.0 { - Inner::Request(req) => req.send_ref(), - Inner::Future(_) => already_polled(), - Inner::Done => done_unreachable(), - } + self.0.send_ref() + } +} + +impl IntoFuture for AutoRequest { + type Output = Result, ::Err>; + type IntoFuture = ::Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() } } @@ -248,75 +228,10 @@ impl HasPayload for AutoRequest { type Payload = R::Payload; fn payload_mut(&mut self) -> &mut Self::Payload { - match &mut self.0 { - Inner::Request(req) => req.payload_mut(), - Inner::Future(_) => already_polled(), - Inner::Done => done_unreachable(), - } + self.0.payload_mut() } fn payload_ref(&self) -> &Self::Payload { - match &self.0 { - Inner::Request(req) => req.payload_ref(), - Inner::Future(_) => already_polled(), - Inner::Done => done_unreachable(), - } + self.0.payload_ref() } } - -impl Future for AutoRequest { - type Output = Result, R::Err>; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let mut this: Pin<&mut Inner<_>> = self.as_mut().project().0; - - match this.as_mut().project() { - // Poll the underling future. - InnerProj::Future(fut) => { - let res = futures::ready!(fut.poll(cx)); - // We've got the result, so we set the state to done. - this.set(Inner::Done); - Poll::Ready(res) - } - - // This future is fused. - InnerProj::Done => Poll::Pending, - // The `AutoRequest` future was polled for the first time after - // creation. We need to transform it into sent form by calling - // `R::send` and doing some magic around Pin. - InnerProj::Request(_) => { - // Replace `Request(_)` by `Done(_)` to obtain ownership over - // the former. - let inner = this.as_mut().project_replace(Inner::Done); - // Map Request(req) to `Future(req.send())`. - let inner = match inner { - InnerRepl::Request(req) => Inner::Future(req.send()), - // Practically this is unreachable, because we've just checked for - // both `Future(_)` and `Done` variants. - InnerRepl::Future(_) | InnerRepl::Done => done_unreachable(), - }; - // Set the resulting `Future(_)` back to pin. - this.set(inner); - - // Poll `self`. This time another brunch will be executed, returning `Poll`. - self.poll(cx) - } - } - } -} - -impl FusedFuture for AutoRequest { - fn is_terminated(&self) -> bool { - matches!(&self.0, Inner::Done) - } -} - -#[inline(never)] -fn done_unreachable() -> ! { - unreachable!("future is completed and as such doesn't provide any functionality") -} - -#[inline(never)] -fn already_polled() -> ! { - panic!("AutoRequest was already polled once") -} diff --git a/src/adaptors/cache_me.rs b/src/adaptors/cache_me.rs index b1918ab8..9d75deaf 100644 --- a/src/adaptors/cache_me.rs +++ b/src/adaptors/cache_me.rs @@ -1,4 +1,5 @@ use std::{pin::Pin, sync::Arc}; +use std::future::IntoFuture; use futures::{ future, @@ -244,6 +245,15 @@ impl> HasPayload for CachedMeRequest { } } +impl> IntoFuture for CachedMeRequest { + type Output = Result; + type IntoFuture = Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() + } +} + type ReadyMe = Ready>; #[pin_project::pin_project] diff --git a/src/adaptors/erased.rs b/src/adaptors/erased.rs index 98dd2c95..fc12d8ac 100644 --- a/src/adaptors/erased.rs +++ b/src/adaptors/erased.rs @@ -1,4 +1,4 @@ -use std::sync::Arc; +use std::{future::IntoFuture, sync::Arc}; use futures::{future::BoxFuture, FutureExt}; use reqwest::Url; @@ -51,7 +51,8 @@ pub struct ErasedRequest<'a, T, E> { inner: Box + 'a>, } -impl<'a, T, E> ErasedRequest<'a, T, E> { +// `T: Payload` required b/c of +impl<'a, T: Payload, E> ErasedRequest<'a, T, E> { pub(crate) fn erase(request: impl Request + 'a) -> Self { Self { inner: Box::new(request), @@ -94,6 +95,19 @@ where } } +impl<'a, T, E> IntoFuture for ErasedRequest<'a, T, E> +where + T: Payload, + E: std::error::Error + Send, +{ + type Output = Result, ::Err>; + type IntoFuture = ::Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() + } +} + /// Object safe version of [`Request`]. /// /// TODO(waffle): make [`Request`] object safe and remove this trait (this is a diff --git a/src/adaptors/throttle/request.rs b/src/adaptors/throttle/request.rs index bf431ebb..29e3a2e5 100644 --- a/src/adaptors/throttle/request.rs +++ b/src/adaptors/throttle/request.rs @@ -1,4 +1,9 @@ -use std::{future::Future, pin::Pin, sync::Arc, time::Instant}; +use std::{ + future::{Future, IntoFuture}, + pin::Pin, + sync::Arc, + time::Instant, +}; use futures::{ future::BoxFuture, @@ -74,6 +79,20 @@ where } } +impl IntoFuture for ThrottlingRequest +where + R: Request + Clone + Send + Sync + 'static, + R::Err: AsResponseParameters + Send, + Output: Send, +{ + type Output = Result, ::Err>; + type IntoFuture = ::Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() + } +} + impl Future for ThrottlingSend where R::Err: AsResponseParameters, diff --git a/src/adaptors/trace.rs b/src/adaptors/trace.rs index a3b3fcfa..7e0e9a78 100644 --- a/src/adaptors/trace.rs +++ b/src/adaptors/trace.rs @@ -1,6 +1,6 @@ use std::{ fmt::Debug, - future::Future, + future::{Future, IntoFuture}, pin::Pin, task::{self, Poll}, }; @@ -309,6 +309,21 @@ where } } +impl IntoFuture for TraceRequest +where + R: Request, + Output: Debug, + R::Err: Debug, + R::Payload: Debug, +{ + type Output = Result, ::Err>; + type IntoFuture = ::Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() + } +} + #[pin_project::pin_project] pub struct Send where diff --git a/src/requests/json.rs b/src/requests/json.rs index fc9e068b..5898cfa2 100644 --- a/src/requests/json.rs +++ b/src/requests/json.rs @@ -1,3 +1,5 @@ +use std::future::IntoFuture; + use serde::{de::DeserializeOwned, Serialize}; use crate::{ @@ -49,6 +51,20 @@ where } } +impl

IntoFuture for JsonRequest

+where + P: 'static, + P: Payload + Serialize, + P::Output: DeserializeOwned, +{ + type Output = Result; + type IntoFuture = ::Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() + } +} + impl

HasPayload for JsonRequest

where P: Payload, diff --git a/src/requests/multipart.rs b/src/requests/multipart.rs index 6aa36dda..6578acd9 100644 --- a/src/requests/multipart.rs +++ b/src/requests/multipart.rs @@ -1,3 +1,5 @@ +use std::future::IntoFuture; + use serde::{de::DeserializeOwned, Serialize}; use crate::{ @@ -50,6 +52,20 @@ where } } +impl

IntoFuture for MultipartRequest

+where + P: 'static, + P: Payload + MultipartPayload + Serialize, + P::Output: DeserializeOwned, +{ + type Output = Result; + type IntoFuture = ::Send; + + fn into_future(self) -> Self::IntoFuture { + self.send() + } +} + impl

HasPayload for MultipartRequest

where P: Payload, diff --git a/src/requests/request.rs b/src/requests/request.rs index ee91232b..393e15c4 100644 --- a/src/requests/request.rs +++ b/src/requests/request.rs @@ -1,7 +1,7 @@ -use std::future::Future; +use std::future::{Future, IntoFuture}; -use either::Either; -use futures::future; +// use either::Either; +// use futures::future; use crate::requests::{HasPayload, Output}; @@ -20,12 +20,11 @@ use crate::requests::{HasPayload, Output}; /// /// [`Throttle`]: crate::adaptors::Throttle #[cfg_attr(all(any(docsrs, dep_docsrs), feature = "nightly"), doc(notable_trait))] -pub trait Request: HasPayload { - /* - * Could be mostly `core::future::IntoFuture` though there is no reason to - * use it before it's integrated in async/await - */ - +pub trait Request +where + Self: HasPayload, + Self: IntoFuture, Self::Err>, IntoFuture = Self::Send>, +{ /// The type of an error that may happen while sending a request to /// Telegram. type Err: std::error::Error + Send; @@ -99,27 +98,29 @@ pub trait Request: HasPayload { } } -impl Request for Either -where - L: Request, - R: Request, -{ - type Err = L::Err; +// FIXME: re-introduce `Either` impls once `Either: IntoFuture` (or make out own `Either`) (same for `Requester`) - type Send = future::Either; +// impl Request for Either +// where +// L: Request, +// R: Request, +// { +// type Err = L::Err; - type SendRef = future::Either; +// type Send = future::Either; - fn send(self) -> Self::Send { - self.map_left(<_>::send) - .map_right(<_>::send) - .either(future::Either::Left, future::Either::Right) - } +// type SendRef = future::Either; - fn send_ref(&self) -> Self::SendRef { - self.as_ref() - .map_left(<_>::send_ref) - .map_right(<_>::send_ref) - .either(future::Either::Left, future::Either::Right) - } -} +// fn send(self) -> Self::Send { +// self.map_left(<_>::send) +// .map_right(<_>::send) +// .either(future::Either::Left, future::Either::Right) +// } + +// fn send_ref(&self) -> Self::SendRef { +// self.as_ref() +// .map_left(<_>::send_ref) +// .map_right(<_>::send_ref) +// .either(future::Either::Left, future::Either::Right) +// } +// } diff --git a/src/requests/requester.rs b/src/requests/requester.rs index bafb7b01..5f65a6cb 100644 --- a/src/requests/requester.rs +++ b/src/requests/requester.rs @@ -1090,30 +1090,30 @@ where forward_all! {} } -macro_rules! fty_either { - ($T:ident) => { - either::Either - }; -} +// macro_rules! fty_either { +// ($T:ident) => { +// either::Either +// }; +// } -macro_rules! fwd_either { - ($m:ident $this:ident ($($arg:ident : $T:ty),*)) => { - match ($this) { - either::Either::Left(l) => either::Either::Left(l.$m($($arg),*)), - either::Either::Right(r) => either::Either::Right(r.$m($($arg),*)), - } - }; -} +// macro_rules! fwd_either { +// ($m:ident $this:ident ($($arg:ident : $T:ty),*)) => { +// match ($this) { +// either::Either::Left(l) => either::Either::Left(l.$m($($arg),*)), +// either::Either::Right(r) => +// either::Either::Right(r.$m($($arg),*)), } +// }; +// } -impl Requester for either::Either -where - LR: Requester, - RR: Requester, -{ - type Err = LR::Err; +// impl Requester for either::Either +// where +// LR: Requester, +// RR: Requester, +// { +// type Err = LR::Err; - forward_all! { fwd_either, fty_either } -} +// forward_all! { fwd_either, fty_either } +// } #[test] fn codegen_requester_methods() { From d541faa6213f6c92d6574b033777862a9f6a1bef Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 17:48:26 +0400 Subject: [PATCH 03/13] Deprecate `AutoSend` --- Cargo.toml | 4 ++-- examples/erased.rs | 4 ++-- examples/self_info.rs | 3 +-- src/adaptors.rs | 2 ++ src/requests/requester_ext.rs | 3 +++ 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 86dba265..2dda612a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,8 +99,8 @@ cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples=examples"] [[example]] name = "self_info" -required-features = ["tokio/macros", "tokio/rt-multi-thread", "auto_send"] +required-features = ["tokio/macros", "tokio/rt-multi-thread"] [[example]] name = "erased" -required-features = ["tokio/macros", "tokio/rt-multi-thread", "auto_send", "erased"] +required-features = ["tokio/macros", "tokio/rt-multi-thread", "erased", "trace_adaptor"] diff --git a/examples/erased.rs b/examples/erased.rs index d980ddc3..2c54123c 100644 --- a/examples/erased.rs +++ b/examples/erased.rs @@ -32,9 +32,9 @@ async fn main() -> Result<(), Box> { log::info!("Trace settings: {:?}", trace_settings); let bot = if trace_settings.is_empty() { - Bot::from_env().erase().auto_send() + Bot::from_env().erase() } else { - Bot::from_env().trace(trace_settings).erase().auto_send() + Bot::from_env().trace(trace_settings).erase() }; bot.send_chat_action(chat_id, ChatAction::Typing).await?; diff --git a/examples/self_info.rs b/examples/self_info.rs index b56271c8..6349b76a 100644 --- a/examples/self_info.rs +++ b/examples/self_info.rs @@ -14,8 +14,7 @@ async fn main() -> Result<(), Box> { ); let bot = Bot::from_env() - .parse_mode(ParseMode::MarkdownV2) - .auto_send(); + .parse_mode(ParseMode::MarkdownV2); let Me { user: me, .. } = bot.get_me().await?; diff --git a/src/adaptors.rs b/src/adaptors.rs index 4f1b7406..8fa3aafd 100644 --- a/src/adaptors.rs +++ b/src/adaptors.rs @@ -14,6 +14,7 @@ /// [`AutoSend`]: auto_send::AutoSend /// [`send`]: crate::requests::Request::send #[cfg(feature = "auto_send")] +#[deprecated(since = "0.8.0", note = "`AutoSend` is no longer required to `.await` requests and is now noop")] pub mod auto_send; /// [`CacheMe`] bot adaptor which caches [`GetMe`] requests. @@ -47,6 +48,7 @@ pub mod throttle; mod parse_mode; #[cfg(feature = "auto_send")] +#[allow(deprecated)] pub use auto_send::AutoSend; #[cfg(feature = "cache_me")] pub use cache_me::CacheMe; diff --git a/src/requests/requester_ext.rs b/src/requests/requester_ext.rs index 0bcf438e..0af1faae 100644 --- a/src/requests/requester_ext.rs +++ b/src/requests/requester_ext.rs @@ -4,6 +4,7 @@ use crate::{adaptors::DefaultParseMode, requests::Requester, types::ParseMode}; use crate::adaptors::CacheMe; #[cfg(feature = "auto_send")] +#[allow(deprecated)] use crate::adaptors::AutoSend; #[cfg(feature = "erased")] @@ -28,6 +29,8 @@ pub trait RequesterExt: Requester { /// Send requests automatically, see [`AutoSend`] for more. #[cfg(feature = "auto_send")] + #[deprecated(since = "0.8.0", note = "`AutoSend` is no longer required to `.await` requests and is now noop")] + #[allow(deprecated)] fn auto_send(self) -> AutoSend where Self: Sized, From 6d79d78c8cb41be8b7feccdad823d7ff8505d5b7 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 18:14:58 +0400 Subject: [PATCH 04/13] Update `pin-project` (this fixes a `dead_code` warning in generated code) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2dda612a..a3e25291 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ exclude = [ futures = "0.3.5" tokio = { version = "1.12.0", features = ["fs"] } tokio-util = { version = "0.7.0", features = ["codec"] } -pin-project = "1.0.3" +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"] } From 69adf7ef1096fbca3979f9290d37abc94c7a1c6b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 18:20:32 +0400 Subject: [PATCH 05/13] Update changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58f99914..9f9aa9eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased +### Changed + +- **You can now `.await` any `Request`!** ([#249][pr249]) + - `Request` now requires `Self: IntoFuture` + - There is no need for `AutoSend` anymore +- MSRV (Minimal Supported Rust Version) was bumped from `1.58.0` to `1.64.0` + ### Removed - Methods for creating `InlineQuery` ([#246][pr244]) [pr244]: https://github.com/teloxide/teloxide-core/pull/246 +### Deprecated + +- `AutoSend` adaptor ([#249][pr249]) + +[pr249]: https://github.com/teloxide/teloxide-core/pull/249 + ## 0.7.1 - 2022-08-19 ### Fixed From 0dc459ffcce351efbb05ba1fbea16028695ec025 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 18:40:07 +0400 Subject: [PATCH 06/13] Doc fixes --- src/adaptors.rs | 5 +---- src/adaptors/auto_send.rs | 34 +++++++++----------------------- src/adaptors/throttle/request.rs | 4 ++-- src/adaptors/throttle/worker.rs | 4 ++-- src/bot.rs | 4 ++-- src/lib.rs | 4 +--- src/net/download.rs | 2 +- src/requests/request.rs | 7 +++++++ src/requests/requester.rs | 5 ++--- 9 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/adaptors.rs b/src/adaptors.rs index 8fa3aafd..142bc4e9 100644 --- a/src/adaptors.rs +++ b/src/adaptors.rs @@ -3,12 +3,9 @@ //! Bot adaptors are very similar to the [`Iterator`] adaptors: they are bots //! wrapping other bots to alter existing or add new functionality. //! -//! E.g. [`AutoSend`] allows `await`ing requests directly, no need to use -//! `.send()`. -//! //! [`Requester`]: crate::requests::Requester -/// [`AutoSend`] bot adaptor which allows sending a request without calling +/// [`AutoSend`] bot adaptor which used to allow sending a request without calling /// [`send`]. /// /// [`AutoSend`]: auto_send::AutoSend diff --git a/src/adaptors/auto_send.rs b/src/adaptors/auto_send.rs index 5c01f081..878e64ff 100644 --- a/src/adaptors/auto_send.rs +++ b/src/adaptors/auto_send.rs @@ -7,32 +7,16 @@ use crate::{ types::*, }; -/// Send requests automatically. +/// Previously was used to send requests automatically. /// -/// Requests returned by ` as `[`Requester`]`>` are [`Future`]s -/// which means that you can simply `.await` them instead of using -/// `.send().await`. -/// -/// Notes: -/// 1. This wrapper should be the most outer i.e.: `AutoSend>` -/// will automatically send requests, while `CacheMe>` - won't. -/// 2. After first call to `poll` on a request you will be unable to access -/// payload nor could you use [`send_ref`](Request::send_ref). -/// -/// ## Examples -/// -/// ```rust -/// use teloxide_core::{ -/// requests::{Requester, RequesterExt}, -/// types::Me, -/// Bot, -/// }; -/// -/// # async { -/// let bot = Bot::new("TOKEN").auto_send(); -/// let myself: Me = bot.get_me().await?; // No .send()! -/// # Ok::<_, teloxide_core::RequestError>(()) }; -/// ``` +/// Before addition of [`IntoFuture`] you could only `.await` [`Future`]s. +/// This adaptor turned requests into futures, allowing to `.await` them, +/// without calling `.send()`. +/// +/// Now, however, all requests are required to implement `IntoFuture`, allowing +/// you to `.await` them directly. This adaptor is noop, and shouldn't be used. +/// +/// [`Future`]: std::future::Future #[derive(Clone, Debug)] pub struct AutoSend { bot: B, diff --git a/src/adaptors/throttle/request.rs b/src/adaptors/throttle/request.rs index 29e3a2e5..46235fce 100644 --- a/src/adaptors/throttle/request.rs +++ b/src/adaptors/throttle/request.rs @@ -178,7 +178,7 @@ where let res = match &mut request { ShareableRequest::Shared(shared) => shared.send_ref().await, - ShareableRequest::Owned(owned) => owned.take().unwrap().send().await, + ShareableRequest::Owned(owned) => owned.take().unwrap().await, }; return res; @@ -197,7 +197,7 @@ where request.send_ref().await } (false, ShareableRequest::Shared(shared)) => shared.send_ref().await, - (false, ShareableRequest::Owned(owned)) => owned.take().unwrap().send().await, + (false, ShareableRequest::Owned(owned)) => owned.take().unwrap().await, }; let retry_after = res.as_ref().err().and_then(<_>::retry_after); diff --git a/src/adaptors/throttle/worker.rs b/src/adaptors/throttle/worker.rs index a3202f4c..62438013 100644 --- a/src/adaptors/throttle/worker.rs +++ b/src/adaptors/throttle/worker.rs @@ -9,7 +9,7 @@ use vecrem::VecExt; use crate::{ adaptors::throttle::{request_lock::RequestLock, ChatIdHash, Limits, Settings}, errors::AsResponseParameters, - requests::{Request, Requester}, + requests::Requester, }; const MINUTE: Duration = Duration::from_secs(60); @@ -321,7 +321,7 @@ async fn freeze( // TODO: maybe not call `get_chat` every time? // At this point there isn't much we can do with the error besides ignoring - if let Ok(chat) = bot.get_chat(id).send().await { + if let Ok(chat) = bot.get_chat(id).await { match chat.slow_mode_delay() { Some(delay) => { let now = Instant::now(); diff --git a/src/bot.rs b/src/bot.rs index 2b3f6893..19bb00d5 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -29,7 +29,7 @@ const TELOXIDE_TOKEN: &str = "TELOXIDE_TOKEN"; /// use teloxide_core::prelude::*; /// /// let bot = Bot::new("TOKEN"); -/// dbg!(bot.get_me().send().await?); +/// dbg!(bot.get_me().await?); /// # Ok::<_, teloxide_core::RequestError>(()) }; /// ``` /// @@ -158,7 +158,7 @@ impl Bot { /// let url = reqwest::Url::parse("https://localhost/tbas").unwrap(); /// let bot = Bot::new("TOKEN").set_api_url(url); /// // From now all methods will use "https://localhost/tbas" as an API URL. - /// bot.get_me().send().await + /// bot.get_me().await /// # }; /// ``` /// diff --git a/src/lib.rs b/src/lib.rs index 4b65f9c9..3a14fc0b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,6 @@ //! _Compiler support: requires rustc 1.58+_. //! //! ``` -//! # #[cfg(feature = "auto_send")] //! # async { //! # let chat_id = teloxide_core::types::ChatId(-1); //! use teloxide_core::{ @@ -20,7 +19,6 @@ //! //! let bot = Bot::from_env() //! .parse_mode(ParseMode::MarkdownV2) -//! .auto_send(); //! //! let me = bot.get_me().await?; //! @@ -46,7 +44,6 @@ //! - `native-tls` = use [`native-tls`] tls implementation (**enabled by //! default**) //! - `rustls` — use [`rustls`] tls implementation -//! - `auto_send` — enables [`AutoSend`] bot adaptor //! - `trace_adaptor` — enables [`Trace`] bot adaptor //! - `erased` — enables [`ErasedRequester`] bot adaptor //! - `throttle` — enables [`Throttle`] bot adaptor @@ -55,6 +52,7 @@ //! - `nightly` — enables nightly-only features, currently: //! - Removes some future boxing using `#![feature(type_alias_impl_trait)]` //! - Used to built docs (`#![feature(doc_cfg, doc_notable_trait)]`) +//! - `auto_send` — enables [`AutoSend`] bot adaptor (deprecated) //! //! [`AutoSend`]: adaptors::AutoSend //! [`Trace`]: adaptors::Trace diff --git a/src/net/download.rs b/src/net/download.rs index da05352d..dcef724f 100644 --- a/src/net/download.rs +++ b/src/net/download.rs @@ -42,7 +42,7 @@ pub trait Download<'w> /// # async fn run() -> Result<(), Box> { /// let bot = Bot::new("TOKEN"); /// - /// let TgFile { file_path, .. } = bot.get_file("*file_id*").send().await?; + /// let TgFile { file_path, .. } = bot.get_file("*file_id*").await?; /// let mut file = File::create("/tmp/test.png").await?; /// bot.download_file(&file_path, &mut file).await?; /// # Ok(()) } diff --git a/src/requests/request.rs b/src/requests/request.rs index 393e15c4..578a050c 100644 --- a/src/requests/request.rs +++ b/src/requests/request.rs @@ -41,6 +41,7 @@ where /// Send this request. /// /// ## Examples + /// /// ``` /// # async { /// use teloxide_core::{ @@ -56,6 +57,11 @@ where /// let method = GetMe::new(); /// let request = JsonRequest::new(bot, method); /// let _: Me = request.send().await.unwrap(); + /// + /// // You can also just await requests, without calling `send`: + /// let method = GetMe::new(); + /// let request = JsonRequest::new(bot, method); + /// let _: Me = request.await.unwrap(); /// # }; /// ``` #[must_use = "Futures are lazy and do nothing unless polled or awaited"] @@ -72,6 +78,7 @@ where /// and then serializing it, this method should just serialize the data.) /// /// ## Examples + /// /// ``` /// # async { /// use teloxide_core::{prelude::*, requests::Request, types::ChatId, Bot}; diff --git a/src/requests/requester.rs b/src/requests/requester.rs index 5f65a6cb..874517bf 100644 --- a/src/requests/requester.rs +++ b/src/requests/requester.rs @@ -32,8 +32,7 @@ use crate::{ /// bot.send_message(chat_id, "Text") /// // Optional parameters can be supplied by calling setters /// .parse_mode(ParseMode::Html) -/// // To send request to telegram you need to call `.send()` and await the resulting future -/// .send() +/// // To send request to telegram you need to `.await` the request /// .await?; /// # Ok::<_, teloxide_core::RequestError>(()) /// # }; @@ -51,7 +50,7 @@ use crate::{ /// where /// R: Requester, /// { -/// bot.send_message(chat, "hi").send().await.expect("error") +/// bot.send_message(chat, "hi").await.expect("error") /// } /// ``` #[cfg_attr(all(any(docsrs, dep_docsrs), feature = "nightly"), doc(notable_trait))] From c96e46dc6cc84ec1dc1a75c692af72068eea2208 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 18:40:54 +0400 Subject: [PATCH 07/13] fmt I'm too lazy to amend commits... --- examples/self_info.rs | 3 +-- src/adaptors.rs | 9 ++++++--- src/adaptors/auto_send.rs | 4 ++-- src/adaptors/cache_me.rs | 3 +-- src/requests/request.rs | 9 +++++---- src/requests/requester_ext.rs | 5 ++++- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/examples/self_info.rs b/examples/self_info.rs index 6349b76a..e3747671 100644 --- a/examples/self_info.rs +++ b/examples/self_info.rs @@ -13,8 +13,7 @@ async fn main() -> Result<(), Box> { .parse::()?, ); - let bot = Bot::from_env() - .parse_mode(ParseMode::MarkdownV2); + let bot = Bot::from_env().parse_mode(ParseMode::MarkdownV2); let Me { user: me, .. } = bot.get_me().await?; diff --git a/src/adaptors.rs b/src/adaptors.rs index 142bc4e9..c54a65ec 100644 --- a/src/adaptors.rs +++ b/src/adaptors.rs @@ -5,13 +5,16 @@ //! //! [`Requester`]: crate::requests::Requester -/// [`AutoSend`] bot adaptor which used to allow sending a request without calling -/// [`send`]. +/// [`AutoSend`] bot adaptor which used to allow sending a request without +/// calling [`send`]. /// /// [`AutoSend`]: auto_send::AutoSend /// [`send`]: crate::requests::Request::send #[cfg(feature = "auto_send")] -#[deprecated(since = "0.8.0", note = "`AutoSend` is no longer required to `.await` requests and is now noop")] +#[deprecated( + since = "0.8.0", + note = "`AutoSend` is no longer required to `.await` requests and is now noop" +)] pub mod auto_send; /// [`CacheMe`] bot adaptor which caches [`GetMe`] requests. diff --git a/src/adaptors/auto_send.rs b/src/adaptors/auto_send.rs index 878e64ff..dfd4a4c8 100644 --- a/src/adaptors/auto_send.rs +++ b/src/adaptors/auto_send.rs @@ -12,10 +12,10 @@ use crate::{ /// Before addition of [`IntoFuture`] you could only `.await` [`Future`]s. /// This adaptor turned requests into futures, allowing to `.await` them, /// without calling `.send()`. -/// +/// /// Now, however, all requests are required to implement `IntoFuture`, allowing /// you to `.await` them directly. This adaptor is noop, and shouldn't be used. -/// +/// /// [`Future`]: std::future::Future #[derive(Clone, Debug)] pub struct AutoSend { diff --git a/src/adaptors/cache_me.rs b/src/adaptors/cache_me.rs index 9d75deaf..5ae8669a 100644 --- a/src/adaptors/cache_me.rs +++ b/src/adaptors/cache_me.rs @@ -1,5 +1,4 @@ -use std::{pin::Pin, sync::Arc}; -use std::future::IntoFuture; +use std::{future::IntoFuture, pin::Pin, sync::Arc}; use futures::{ future, diff --git a/src/requests/request.rs b/src/requests/request.rs index 578a050c..d39c9d64 100644 --- a/src/requests/request.rs +++ b/src/requests/request.rs @@ -41,7 +41,7 @@ where /// Send this request. /// /// ## Examples - /// + /// /// ``` /// # async { /// use teloxide_core::{ @@ -57,7 +57,7 @@ where /// let method = GetMe::new(); /// let request = JsonRequest::new(bot, method); /// let _: Me = request.send().await.unwrap(); - /// + /// /// // You can also just await requests, without calling `send`: /// let method = GetMe::new(); /// let request = JsonRequest::new(bot, method); @@ -78,7 +78,7 @@ where /// and then serializing it, this method should just serialize the data.) /// /// ## Examples - /// + /// /// ``` /// # async { /// use teloxide_core::{prelude::*, requests::Request, types::ChatId, Bot}; @@ -105,7 +105,8 @@ where } } -// FIXME: re-introduce `Either` impls once `Either: IntoFuture` (or make out own `Either`) (same for `Requester`) +// FIXME: re-introduce `Either` impls once `Either: IntoFuture` (or make out own +// `Either`) (same for `Requester`) // impl Request for Either // where diff --git a/src/requests/requester_ext.rs b/src/requests/requester_ext.rs index 0af1faae..35509409 100644 --- a/src/requests/requester_ext.rs +++ b/src/requests/requester_ext.rs @@ -29,7 +29,10 @@ pub trait RequesterExt: Requester { /// Send requests automatically, see [`AutoSend`] for more. #[cfg(feature = "auto_send")] - #[deprecated(since = "0.8.0", note = "`AutoSend` is no longer required to `.await` requests and is now noop")] + #[deprecated( + since = "0.8.0", + note = "`AutoSend` is no longer required to `.await` requests and is now noop" + )] #[allow(deprecated)] fn auto_send(self) -> AutoSend where From bd522b70f1a6854d25d48d969d659942150ff9ff Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 18:56:58 +0400 Subject: [PATCH 08/13] fix CI --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5143bb29..f05f9948 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,6 +102,7 @@ jobs: profile: minimal toolchain: ${{ matrix.toolchain }} override: true + components: rustfmt # required by codegen - name: Cache Dependencies uses: Swatinem/rust-cache@v1 From 02e34bc77afee5b9e0af92bfcd44ad010cfed959 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 18:58:02 +0400 Subject: [PATCH 09/13] fix MSRV in docs --- README.md | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e3aedce7..25e08273 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ ```toml teloxide-core = "0.7" ``` -_Compiler support: requires rustc 1.58+_. +_Compiler support: requires rustc 1.64+_. [`teloxide`]: https://docs.rs/teloxide [Telegram Bot API]: https://core.telegram.org/bots/api diff --git a/src/lib.rs b/src/lib.rs index 3a14fc0b..e904f6a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //!```toml //! teloxide_core = "0.7" //! ``` -//! _Compiler support: requires rustc 1.58+_. +//! _Compiler support: requires rustc 1.64+_. //! //! ``` //! # async { From 86cac381e73ae89af9adcc3539f03083e6982d1c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 19:06:11 +0400 Subject: [PATCH 10/13] Use correct toolchain for codegen --- src/codegen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen.rs b/src/codegen.rs index 5f80912b..c26575f1 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -23,7 +23,7 @@ use xshell::{cmd, Shell}; fn ensure_rustfmt(sh: &Shell) { // FIXME(waffle): find a better way to set toolchain - let toolchain = "nightly-2022-01-17"; + let toolchain = "nightly-2022-09-23"; let version = cmd!(sh, "rustup run {toolchain} rustfmt --version") .read() @@ -38,7 +38,7 @@ fn ensure_rustfmt(sh: &Shell) { } pub fn reformat(text: String) -> String { - let toolchain = "nightly-2022-01-17"; + let toolchain = "nightly-2022-09-23"; let sh = Shell::new().unwrap(); ensure_rustfmt(&sh); From 2a20fdd1c05cea0b981ae6b2c2a5a62e88cecbc7 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 22:42:53 +0400 Subject: [PATCH 11/13] fix doc tests --- src/lib.rs | 2 +- src/requests/request.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e904f6a5..8d343f72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ //! }; //! //! let bot = Bot::from_env() -//! .parse_mode(ParseMode::MarkdownV2) +//! .parse_mode(ParseMode::MarkdownV2); //! //! let me = bot.get_me().await?; //! diff --git a/src/requests/request.rs b/src/requests/request.rs index d39c9d64..bd5113af 100644 --- a/src/requests/request.rs +++ b/src/requests/request.rs @@ -56,12 +56,11 @@ where /// // Note: it's recommended to `Requester` instead of creating requests directly /// let method = GetMe::new(); /// let request = JsonRequest::new(bot, method); + /// let request_clone = request.clone(); /// let _: Me = request.send().await.unwrap(); /// /// // You can also just await requests, without calling `send`: - /// let method = GetMe::new(); - /// let request = JsonRequest::new(bot, method); - /// let _: Me = request.await.unwrap(); + /// let _: Me = request_clone.await.unwrap(); /// # }; /// ``` #[must_use = "Futures are lazy and do nothing unless polled or awaited"] From 28deda130eeea29f43e39d97e9e683021e3ec703 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 22:48:24 +0400 Subject: [PATCH 12/13] fmt (I am a joke) --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8d343f72..46fd908b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,8 +17,7 @@ //! types::{DiceEmoji, ParseMode}, //! }; //! -//! let bot = Bot::from_env() -//! .parse_mode(ParseMode::MarkdownV2); +//! let bot = Bot::from_env().parse_mode(ParseMode::MarkdownV2); //! //! let me = bot.get_me().await?; //! From 995a482f8130a785c898a737facbe478d9751734 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 23 Sep 2022 22:59:04 +0400 Subject: [PATCH 13/13] silence clippy --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 46fd908b..5e92048c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,6 +90,13 @@ #![allow(clippy::return_self_not_must_use)] // Workaround for CI #![allow(rustdoc::bare_urls)] +// FIXME: deal with these lints +#![allow( + clippy::collapsible_str_replace, + clippy::borrow_deref_ref, + clippy::unnecessary_lazy_evaluations, + clippy::derive_partial_eq_without_eq +)] // The internal helper macros. #[macro_use]