From 80a586575228b1e456fe09eab3a92315009c5e1b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 3 Oct 2022 21:10:32 +0400 Subject: [PATCH 01/10] Start writing migration guide --- MIGRATION_GUIDE.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 78003f48..ec2f7a6c 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -1,6 +1,59 @@ 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. +## 0.10 -> 0.11 + +### core + +Requests can now be `.await`ed directly, without need of `.send()` or `AutoSend`. +If you previously used `AutoSend` adaptor, you can safely remove it. + +`File`'s and `FileMeta`'s fields now don't have `file_` prefix. +If you previously accessed the fields, you'll need to change remove the prefix: + +```diff +-_ = file.file_size; ++_ = file.size; +``` + +`Animation`, `Audio`, `Document`, `PassportFile`, `PhotoSize`, `Video`, `VideoNote` and `Voice` now contain `FileMeta` instead of its fields. +Together with rename of `FileMeta`'s fields, you'll need to change `_` to `.`: + +```diff +-_ = animation.file_size; ++_ = animation.file.size; +``` + +Message id fields and parameters now use `MessageId` type, instead of `i32`. +You may need to change code accordingly: + +```diff +-let id: i32 = message.id; ++let id: MessageId = message.id; +``` +```diff,rust +let (cid, mid): (ChatId, i32) = get_message_to_delete_from_db(); +-bot.delete_message(cid, mid).await?; ++bot.delete_message(cid, MessageId(mid)).await?; +``` + +Note that at the same time `MessageId` is now a tuple struct. +If you've accessed its only field you'll need to change it too: + +```diff,rust +-let MessageId { message_id } = bot.copy_message(dst_chat, src_chat, mid).await?; ++let MessageId(message_id) = bot.copy_message(dst_chat, src_chat, mid).await?; +save_to_db(message_id); +``` + +Because of API updates `Sticker` type was refactored again. +You may need to change code accordingly. +See `Sticker` documentation for more information about the new structure. + +### teloxide + + + ## 0.9 -> 0.10 ### core From c4dbff1afe349d3eec11ab7e05ab660e9ee97482 Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Tue, 4 Oct 2022 09:56:51 +0600 Subject: [PATCH 02/10] Enhance the v0.11 migration guide --- MIGRATION_GUIDE.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index ec2f7a6c..c0e3566c 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -6,7 +6,17 @@ Note that the list of required changes is not fully exhaustive and it may lack s ### core Requests can now be `.await`ed directly, without need of `.send()` or `AutoSend`. -If you previously used `AutoSend` adaptor, you can safely remove it. +If you previously used `AutoSend` adaptor, you can safely remove it: + +```diff,rust +-let bot = Bot::from_env().auto_send(); ++let bot = Bot::from_env(); +``` + +```diff,rust +-async fn start(bot: AutoSend, dialogue: MyDialogue, msg: Message) -> HandlerResult { ++async fn start(bot: Bot, dialogue: MyDialogue, msg: Message) -> HandlerResult { +``` `File`'s and `FileMeta`'s fields now don't have `file_` prefix. If you previously accessed the fields, you'll need to change remove the prefix: @@ -52,7 +62,18 @@ See `Sticker` documentation for more information about the new structure. ### teloxide - +You can now write `Ok(())` instead of `respond(())` at the end of closures provided to RELPs: + +```diff,rust +teloxide::repl(bot, |bot: Bot, msg: Message| async move { + bot.send_dice(msg.chat.id).await?; +- respond(()) ++ Ok(()) +}) +.await; +``` + +This is because REPLs now require the closure to return `RequestError` instead of a generic error type, so type inference works perfectly for a return value. If you use something other than `RequestError`, you can transfer your code to `teloxide::dispatching`, which still permits a generic error type. ## 0.9 -> 0.10 From 59b5047fa362673633544600214cbe11f3b09e5d Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 09:55:58 +0600 Subject: [PATCH 03/10] Update the migration guide with `BotCommands` changes --- MIGRATION_GUIDE.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index c0e3566c..9860c54c 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -75,6 +75,32 @@ teloxide::repl(bot, |bot: Bot, msg: Message| async move { This is because REPLs now require the closure to return `RequestError` instead of a generic error type, so type inference works perfectly for a return value. If you use something other than `RequestError`, you can transfer your code to `teloxide::dispatching`, which still permits a generic error type. +`parse_with` now accepts a Rust _path_ to a custom parser function instead of a string: + +```diff,rust +fn custom_parser(input: String) -> Result<(u8,), ParseError> { + todo!() +} + +#[derive(BotCommands)] +enum Command { +- #[command(parse_with = "custom_parser")] ++ #[command(parse_with = custom_parser)] + Num(u8), +} +``` + +`rename` now only renames a command literally; use `rename_rule` to change the case of a command: + +```diff,rust +#[derive(BotCommands)] +- #[command(rename = "lowercase", description = "These commands are supported:")] ++ #[command(rename_rule = "lowercase", description = "These commands are supported:")] +enum Command { + // ... +} +``` + ## 0.9 -> 0.10 ### core From fe3aa2e7983db0fe0457063429fa108338cbc020 Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 10:14:36 +0600 Subject: [PATCH 04/10] Refactor `dptree` usage --- src/dispatching/dialogue.rs | 25 ++++++++++++------------- src/dispatching/handler_ext.rs | 4 ++-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/dispatching/dialogue.rs b/src/dispatching/dialogue.rs index c8d27896..89d16326 100644 --- a/src/dispatching/dialogue.rs +++ b/src/dispatching/dialogue.rs @@ -220,18 +220,17 @@ where Upd: GetChatId + Clone + Send + Sync + 'static, Output: Send + Sync + 'static, { - dptree::entry() - .chain(dptree::filter_map(|storage: Arc, upd: Upd| { - let chat_id = upd.chat_id()?; - Some(Dialogue::new(storage, chat_id)) - })) - .chain(dptree::filter_map_async(|dialogue: Dialogue| async move { - match dialogue.get_or_default().await { - Ok(dialogue) => Some(dialogue), - Err(err) => { - log::error!("dialogue.get_or_default() failed: {:?}", err); - None - } + dptree::filter_map(|storage: Arc, upd: Upd| { + let chat_id = upd.chat_id()?; + Some(Dialogue::new(storage, chat_id)) + }) + .filter_map_async(|dialogue: Dialogue| async move { + match dialogue.get_or_default().await { + Ok(dialogue) => Some(dialogue), + Err(err) => { + log::error!("dialogue.get_or_default() failed: {:?}", err); + None } - })) + } + }) } diff --git a/src/dispatching/handler_ext.rs b/src/dispatching/handler_ext.rs index 932d5079..0013acb4 100644 --- a/src/dispatching/handler_ext.rs +++ b/src/dispatching/handler_ext.rs @@ -88,8 +88,8 @@ where C: BotCommands + Send + Sync + 'static, Output: Send + Sync + 'static, { - dptree::entry().chain(dptree::filter_map(move |message: Message, me: Me| { + dptree::filter_map(move |message: Message, me: Me| { let bot_name = me.user.username.expect("Bots must have a username"); message.text().and_then(|text| C::parse(text, &bot_name).ok()) - })) + }) } From 6043f5566e02dd7a9c72ee6c2c56bfa904ea5d04 Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 10:38:52 +0600 Subject: [PATCH 05/10] Update the 'Highlights' section I've simplified the point about dialogues and added the point "Feature-rich", which mentions some functionality typically asked by users in our support chat. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ab74b6d7..ae498ce6 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,9 @@ [`dptree`]: https://github.com/teloxide/dptree [chain of responsibility]: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern - - **Dialogues management subsystem.** Our dialogues management subsystem is simple and easy-to-use, and, furthermore, is agnostic of how/where dialogues are stored. For example, you can just replace a one line to achieve [persistence]. Out-of-the-box storages include [Redis] and [Sqlite]. + - **Feature-rich.** You can use both long polling and webhooks, configure an underlying HTTPS client, set a custom URL of a Telegram API server, and a lot more. + + - **Simple dialogues.** Our dialogues subsystem is simple and easy-to-use, and, furthermore, is agnostic of how/where dialogues are stored. For example, you can just replace a one line to achieve [persistence]. Out-of-the-box storages include [Redis] and [Sqlite]. [persistence]: https://en.wikipedia.org/wiki/Persistence_(computer_science) [Redis]: https://redis.io/ From 6966ab9ce111e7e932d852f51d560e4b64e7d491 Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 10:45:35 +0600 Subject: [PATCH 06/10] Simplify the highlights more --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ae498ce6..da4d421a 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ [Redis]: https://redis.io/ [Sqlite]: https://www.sqlite.org - - **Strongly typed commands.** You can describe bot commands as enumerations, and then they'll be automatically constructed from strings — just like JSON structures in [`serde-json`] and command-line arguments in [`structopt`]. + - **Strongly typed commands.** Define bot commands as an `enum` and teloxide will parse them automatically — just like JSON structures in [`serde-json`] and command-line arguments in [`structopt`]. [`structopt`]: https://github.com/TeXitoi/structopt [`serde-json`]: https://github.com/serde-rs/json From 3d65f81eae9c57a47e2cccdc2850f613bbda99cc Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 16:30:33 +0600 Subject: [PATCH 07/10] Apply a tiny review suggestion Co-authored-by: Waffle Maybe --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da4d421a..7c726708 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ [`dptree`]: https://github.com/teloxide/dptree [chain of responsibility]: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern - - **Feature-rich.** You can use both long polling and webhooks, configure an underlying HTTPS client, set a custom URL of a Telegram API server, and a lot more. + - **Feature-rich.** You can use both long polling and webhooks, configure an underlying HTTPS client, set a custom URL of a Telegram API server, and much more. - **Simple dialogues.** Our dialogues subsystem is simple and easy-to-use, and, furthermore, is agnostic of how/where dialogues are stored. For example, you can just replace a one line to achieve [persistence]. Out-of-the-box storages include [Redis] and [Sqlite]. From 1ab5bdfc77e7899791dcf6d21e075146255656d9 Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 16:34:42 +0600 Subject: [PATCH 08/10] Use consistent naming of our crates --- CHANGELOG.md | 4 ++-- CODE_STYLE.md | 1 + README.md | 12 ++++++------ src/dispatching/repls/commands_repl.rs | 4 ++-- src/dispatching/repls/repl.rs | 4 ++-- src/dispatching/update_listeners/polling.rs | 2 +- src/dispatching/update_listeners/webhooks.rs | 2 +- src/features.md | 4 ++-- 8 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f83a4fb..4a1ce0bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,7 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add the `Key: Clone` requirement for `impl Dispatcher` [**BC**]. - `dispatching::update_listeners::{polling_default, polling}` now return a named, `Polling<_>` type. -- Update teloxide-core to v0.7.0 with Bot API 6.1 support, see [its changelog][core07c] for more information [**BC**]. +- Update `teloxide-core` to v0.7.0 with Bot API 6.1 support, see [its changelog][core07c] for more information [**BC**]. [core07c]: https://github.com/teloxide/teloxide-core/blob/master/CHANGELOG.md#070---2022-07-19 @@ -90,7 +90,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Update teloxide-core to v0.6.0 with [Bot API 6.0] support [**BC**]. +- Update `teloxide-core` to v0.6.0 with [Bot API 6.0] support [**BC**]. [Bot API 6.0]: https://core.telegram.org/bots/api#april-16-2022 diff --git a/CODE_STYLE.md b/CODE_STYLE.md index 77803ce3..40b65d86 100644 --- a/CODE_STYLE.md +++ b/CODE_STYLE.md @@ -83,6 +83,7 @@ impl Trait for Wrap { ... } /// [`tokio::fs::File`]: tokio::fs::File /// [`Bot::download_file`]: crate::Bot::download_file ``` +4. Write `teloxide`, `teloxide-macros`, and `teloxide-core`, not "teloxide", "Teloxide", "teloxide-macros" or any other variant. ## Use `Self` where possible diff --git a/README.md b/README.md index ab74b6d7..01955c35 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
-

teloxide

+

`teloxide`

@@ -24,7 +24,7 @@ ## Highlights - - **Declarative design.** teloxide is based upon [`dptree`], a functional [chain of responsibility] pattern that allows you to express pipelines of message processing in a highly declarative and extensible style. + - **Declarative design.** `teloxide` is based upon [`dptree`], a functional [chain of responsibility] pattern that allows you to express pipelines of message processing in a highly declarative and extensible style. [`dptree`]: https://github.com/teloxide/dptree [chain of responsibility]: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern @@ -56,7 +56,7 @@ $ set TELOXIDE_TOKEN= $ $env:TELOXIDE_TOKEN= ``` - 4. Make sure that your Rust compiler is up to date (teloxide currently requires rustc at least version 1.58): + 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.58): ```bash # If you're using stable $ rustup update stable @@ -304,7 +304,7 @@ A: No, only the bots API. **Q: Can I use webhooks?** -A: You can! Teloxide has a built-in support for webhooks in `dispatching::update_listeners::webhooks` module. See how it's used in [`examples/ngrok_ping_pong_bot`](examples/ngrok_ping_pong.rs) and [`examples/heroku_ping_pong_bot`](examples/heroku_ping_pong.rs). +A: You can! `teloxide` has a built-in support for webhooks in `dispatching::update_listeners::webhooks` module. See how it's used in [`examples/ngrok_ping_pong_bot`](examples/ngrok_ping_pong.rs) and [`examples/heroku_ping_pong_bot`](examples/heroku_ping_pong.rs). **Q: Can I handle both callback queries and messages within a single dialogue?** @@ -328,7 +328,7 @@ Feel free to propose your own bot to our collection! - [`zamazan4ik/npaperbot-telegram`](https://github.com/zamazan4ik/npaperbot-telegram) — Telegram bot for searching via C++ proposals.
-Show bots using teloxide older than v0.6.0 +Show bots using `teloxide` older than v0.6.0 - [`mxseev/logram`](https://github.com/mxseev/logram) — Utility that takes logs from anywhere and sends them to Telegram. - [`alexkonovalov/PedigreeBot`](https://github.com/alexkonovalov/PedigreeBot) — A Telegram bot for building family trees. @@ -340,7 +340,7 @@ Feel free to propose your own bot to our collection!
-See [700+ other public repositories using teloxide >>](https://github.com/teloxide/teloxide/network/dependents) +See [700+ other public repositories using `teloxide` >>](https://github.com/teloxide/teloxide/network/dependents) ## Contributing diff --git a/src/dispatching/repls/commands_repl.rs b/src/dispatching/repls/commands_repl.rs index d4e82954..fe9d9fb7 100644 --- a/src/dispatching/repls/commands_repl.rs +++ b/src/dispatching/repls/commands_repl.rs @@ -37,7 +37,7 @@ use std::{fmt::Debug, marker::PhantomData}; /// /// ## Handler arguments /// -/// Teloxide provides the following types to the `handler`: +/// `teloxide` provides the following types to the `handler`: /// - [`Message`] /// - `R` (type of the `bot`) /// - `Cmd` (type of the parsed command) @@ -105,7 +105,7 @@ where /// /// ## Handler arguments /// -/// Teloxide provides the following types to the `handler`: +/// `teloxide` provides the following types to the `handler`: /// - [`Message`] /// - `R` (type of the `bot`) /// - `Cmd` (type of the parsed command) diff --git a/src/dispatching/repls/repl.rs b/src/dispatching/repls/repl.rs index fd26e6e2..b352d8e3 100644 --- a/src/dispatching/repls/repl.rs +++ b/src/dispatching/repls/repl.rs @@ -27,7 +27,7 @@ use std::fmt::Debug; /// /// ## Handler arguments /// -/// Teloxide provides the following types to the `handler`: +/// `teloxide` provides the following types to the `handler`: /// - [`Message`] /// - `R` (type of the `bot`) /// - [`Me`] @@ -81,7 +81,7 @@ where /// /// ## Handler arguments /// -/// Teloxide provides the following types to the `handler`: +/// `teloxide` provides the following types to the `handler`: /// - [`Message`] /// - `R` (type of the `bot`) /// - [`Me`] diff --git a/src/dispatching/update_listeners/polling.rs b/src/dispatching/update_listeners/polling.rs index 1543b322..5fb863f0 100644 --- a/src/dispatching/update_listeners/polling.rs +++ b/src/dispatching/update_listeners/polling.rs @@ -67,7 +67,7 @@ where /// /// ## Note /// - /// Teloxide normally (when using [`Dispatcher`] or [`repl`]s) sets this + /// `teloxide` normally (when using [`Dispatcher`] or [`repl`]s) sets this /// automatically via [`hint_allowed_updates`], so you rarely need to use /// `allowed_updates` explicitly. /// diff --git a/src/dispatching/update_listeners/webhooks.rs b/src/dispatching/update_listeners/webhooks.rs index ef94fec4..e327016b 100644 --- a/src/dispatching/update_listeners/webhooks.rs +++ b/src/dispatching/update_listeners/webhooks.rs @@ -49,7 +49,7 @@ pub struct Options { /// `a-z`, `0-9`, `_` and `-` are allowed. The header is useful to ensure /// that the request comes from a webhook set by you. /// - /// Default - teloxide will generate a random token. + /// Default - `teloxide` will generate a random token. pub secret_token: Option, } diff --git a/src/features.md b/src/features.md index c7aa4e6a..1545af78 100644 --- a/src/features.md +++ b/src/features.md @@ -12,7 +12,7 @@ | `trace-adaptor` | Enables the [`Trace`](adaptors::Trace) bot adaptor. | | `erased` | Enables the [`ErasedRequester`](adaptors::ErasedRequester) bot adaptor. | | `full` | Enables all the features except `nightly`. | -| `nightly` | Enables nightly-only features (see the [teloxide-core features]). | +| `nightly` | Enables nightly-only features (see the [`teloxide-core` features]). | | `native-tls` | Enables the [`native-tls`] TLS implementation (**enabled by default**). | | `rustls` | Enables the [`rustls`] TLS implementation. | | `redis-storage` | Enables the [Redis] storage support for dialogues. | @@ -29,6 +29,6 @@ [`native-tls`]: https://docs.rs/native-tls [`rustls`]: https://docs.rs/rustls [`teloxide::utils::UpState`]: utils::UpState -[teloxide-core features]: https://docs.rs/teloxide-core/latest/teloxide_core/#cargo-features +[`teloxide-core` features]: https://docs.rs/teloxide-core/latest/teloxide_core/#cargo-features [`DispatcherBuilder::enable_ctrlc_handler`]: dispatching::DispatcherBuilder::enable_ctrlc_handler \ No newline at end of file From 60f0cd128db6819f98e430ef22b780e93f9d3847 Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 16:39:49 +0600 Subject: [PATCH 09/10] Use `teloxide` in `README.md` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01955c35..5d48677d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
-

`teloxide`

+

teloxide

From d690709dfb585adab582fbff54eb7ffecc3975ba Mon Sep 17 00:00:00 2001 From: Hirrolot Date: Fri, 7 Oct 2022 16:45:16 +0600 Subject: [PATCH 10/10] Apply a review suggestion Co-authored-by: Waffle Maybe --- MIGRATION_GUIDE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 9860c54c..83ea0829 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -75,6 +75,8 @@ teloxide::repl(bot, |bot: Bot, msg: Message| async move { This is because REPLs now require the closure to return `RequestError` instead of a generic error type, so type inference works perfectly for a return value. If you use something other than `RequestError`, you can transfer your code to `teloxide::dispatching`, which still permits a generic error type. +### macros + `parse_with` now accepts a Rust _path_ to a custom parser function instead of a string: ```diff,rust