From 8d4731d6d608bc5a698553d9b3fb567974d7a986 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Tue, 15 Oct 2019 21:31:58 +0600 Subject: [PATCH 01/66] Rename the project to 'telebofr' It means 'Telegram Bot For Rust' --- Cargo.toml | 2 +- LICENSE | 2 +- README.md | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6c7b54f3..6b662740 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "async-telegram-bot" +name = "telebofr" version = "0.1.0" edition = "2018" diff --git a/LICENSE b/LICENSE index 75a50a58..edb41b3e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 async-telegram-bot +Copyright (c) 2019 telebofr Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1a35a603..e91ace20 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ <div align="center"> - <h1>async-telegram-bot</h1> + <h1>telebofr</h1> - <a href="https://docs.rs/async-telegram-bot/"> + <a href="https://docs.rs/telebofr/"> <img src="https://img.shields.io/badge/docs.rs-link-blue.svg"> </a> - <a href="https://travis-ci.com/async-telegram-bot/async-telegram-bot"> - <img src="https://travis-ci.com/async-telegram-bot/async-telegram-bot.svg?branch=dev" /> + <a href="https://travis-ci.com/telebofr/telebofr"> + <img src="https://travis-ci.com/telebofr/telebofr.svg?branch=dev" /> </a> <a href="LICENSE"> <img src="https://img.shields.io/badge/license-MIT-blue.svg"> </a> - <a href="https://crates.io/crates/async-telegram-bot"> + <a href="https://crates.io/crates/telebofr"> <img src="https://img.shields.io/badge/crates.io-v0.1.0-orange.svg"> </a> From 6d8ef9e1588922344aa53910f8b5ae72150117f6 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Tue, 15 Oct 2019 23:11:05 +0600 Subject: [PATCH 02/66] Update README.md --- README.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/README.md b/README.md index e91ace20..4c39b6b4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ <a href="https://docs.rs/telebofr/"> <img src="https://img.shields.io/badge/docs.rs-link-blue.svg"> </a> - <a href="https://travis-ci.com/telebofr/telebofr"> + <a href="https://travis-ci.com/async-telegram-bot/async-telegram-bot"> <img src="https://travis-ci.com/telebofr/telebofr.svg?branch=dev" /> </a> <a href="LICENSE"> @@ -21,10 +21,3 @@ A full-featured framework that empowers you to easily build [Telegram bots](https://telegram.org/blog/bot-revolution) using the [`async`/`.await`](https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html) syntax in [Rust](https://www.rust-lang.org/). It handles all the difficult stuff so you can focus only on your business logic. </div> - -## A simple bot -```rust -fn main() { - let bot = Bot::new(API_TOKEN).bla().bla(); -} -``` From 148944fc4a4eca493ddca36b1952be6d0b57f32e Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Tue, 15 Oct 2019 23:15:22 +0600 Subject: [PATCH 03/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c39b6b4..9f01fee6 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ <a href="https://docs.rs/telebofr/"> <img src="https://img.shields.io/badge/docs.rs-link-blue.svg"> </a> - <a href="https://travis-ci.com/async-telegram-bot/async-telegram-bot"> + <a href="https://travis-ci.com/telebofr/telebofr"> <img src="https://travis-ci.com/telebofr/telebofr.svg?branch=dev" /> </a> <a href="LICENSE"> From 87e04b491f8b677c35b5eeca6e51a3be3b183e03 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Tue, 15 Oct 2019 23:21:02 +0600 Subject: [PATCH 04/66] Fix the errors --- src/bot/download.rs | 4 ++-- src/dispatcher/filter.rs | 28 ++++++++++++++-------------- src/dispatcher/simple/mod.rs | 2 +- src/types/inline_keyboard_button.rs | 2 +- src/types/inline_keyboard_markup.rs | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/bot/download.rs b/src/bot/download.rs index d711f151..c6100791 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -16,11 +16,11 @@ impl Bot { /// ## Examples /// /// ```no_run - /// use async_telegram_bot::{ + /// use telebofr::{ /// bot::Bot, requests::Request, types::File as TgFile, /// }; /// use tokio::fs::File; - /// # use async_telegram_bot::RequestError; + /// # use telebofr::RequestError; /// /// # async fn run() -> Result<(), Box<dyn std::error::Error>> { /// let bot = Bot::new("TOKEN"); diff --git a/src/dispatcher/filter.rs b/src/dispatcher/filter.rs index e1c267ad..d5afadf5 100644 --- a/src/dispatcher/filter.rs +++ b/src/dispatcher/filter.rs @@ -6,7 +6,7 @@ pub trait Filter<T> { } /// ``` -/// use async_telegram_bot::dispatcher::filter::Filter; +/// use telebofr::dispatcher::filter::Filter; /// /// let closure = |i: &i32| -> bool { *i >= 42 }; /// assert!(closure.test(&42)); @@ -22,7 +22,7 @@ impl<T, F: Fn(&T) -> bool> Filter<T> for F { } /// ``` -/// use async_telegram_bot::dispatcher::filter::Filter; +/// use telebofr::dispatcher::filter::Filter; /// /// assert!(true.test(&())); /// assert_eq!(false.test(&()), false); @@ -40,7 +40,7 @@ impl<T> Filter<T> for bool { /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{And, Filter}; +/// use telebofr::dispatcher::filter::{And, Filter}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert_eq!(And::new(true, false).test(&()), false); @@ -71,7 +71,7 @@ where /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{and, Filter}; +/// use telebofr::dispatcher::filter::{and, Filter}; /// /// assert!(and(true, true).test(&())); /// assert_eq!(and(true, false).test(&()), false); @@ -92,7 +92,7 @@ pub fn and<A, B>(a: A, b: B) -> And<A, B> { /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{Or, Filter}; +/// use telebofr::dispatcher::filter::{Or, Filter}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Or::new(true, false).test(&())); @@ -123,7 +123,7 @@ where /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{or, Filter}; +/// use telebofr::dispatcher::filter::{or, Filter}; /// /// assert!(or(true, false).test(&())); /// assert_eq!(or(false, false).test(&()), false); @@ -141,7 +141,7 @@ pub fn or<A, B>(a: A, b: B) -> Or<A, B> { /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{Not, Filter}; +/// use telebofr::dispatcher::filter::{Not, Filter}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Not::new(false).test(&())); @@ -169,7 +169,7 @@ where /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{not, Filter}; +/// use telebofr::dispatcher::filter::{not, Filter}; /// /// assert!(not(false).test(&())); /// assert_eq!(not(true).test(&()), false); @@ -187,7 +187,7 @@ pub fn not<A>(a: A) -> Not<A> { /// /// ## Examples /// ``` -/// use async_telegram_bot::{all, dispatcher::filter::Filter}; +/// use telebofr::{all, dispatcher::filter::Filter}; /// /// assert!(all![true].test(&())); /// assert!(all![true, true].test(&())); @@ -218,7 +218,7 @@ macro_rules! all { /// /// ## Examples /// ``` -/// use async_telegram_bot::{any, dispatcher::filter::Filter}; +/// use telebofr::{any, dispatcher::filter::Filter}; /// /// assert!(any![true].test(&())); /// assert!(any![true, true].test(&())); @@ -247,7 +247,7 @@ macro_rules! any { /// /// ## Examples /// ``` -/// use async_telegram_bot::dispatcher::filter::{Filter, f, F, And, Or}; +/// use telebofr::dispatcher::filter::{Filter, f, F, And, Or}; /// /// let flt1 = |i: &i32| -> bool { *i > 17 }; /// let flt2 = |i: &i32| -> bool { *i < 42 }; @@ -316,7 +316,7 @@ pub trait FilterExt<T /* workaround for `E0207` compiler error */> { /// /// ## Examples /// ``` - /// use async_telegram_bot::dispatcher::filter::{Filter, FilterExt}; + /// use telebofr::dispatcher::filter::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i > 0 }; /// let flt = flt.not(); @@ -333,7 +333,7 @@ pub trait FilterExt<T /* workaround for `E0207` compiler error */> { /// /// ## Examples /// ``` - /// use async_telegram_bot::dispatcher::filter::{Filter, FilterExt}; + /// use telebofr::dispatcher::filter::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i > 0 }; /// let flt = flt.and(|i: &i32| *i < 42); @@ -352,7 +352,7 @@ pub trait FilterExt<T /* workaround for `E0207` compiler error */> { /// /// ## Examples /// ``` - /// use async_telegram_bot::dispatcher::filter::{Filter, FilterExt}; + /// use telebofr::dispatcher::filter::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i < 0 }; /// let flt = flt.or(|i: &i32| *i > 42); diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 63ce3a28..83400bcb 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -40,7 +40,7 @@ type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E /// ```no_run /// # async fn run() { /// use std::convert::Infallible; -/// use async_telegram_bot::{ +/// use telebofr::{ /// bot::Bot, /// types::Message, /// dispatcher::{ diff --git a/src/types/inline_keyboard_button.rs b/src/types/inline_keyboard_button.rs index 27ef8896..935a38c4 100644 --- a/src/types/inline_keyboard_button.rs +++ b/src/types/inline_keyboard_button.rs @@ -45,7 +45,7 @@ pub enum InlineKeyboardButtonKind { /// /// Example: /// ``` -/// use async_telegram_bot::types::InlineKeyboardButton; +/// use telebofr::types::InlineKeyboardButton; /// /// let url_button = InlineKeyboardButton::url( /// "Text".to_string(), diff --git a/src/types/inline_keyboard_markup.rs b/src/types/inline_keyboard_markup.rs index 67bd2aa8..e52fccda 100644 --- a/src/types/inline_keyboard_markup.rs +++ b/src/types/inline_keyboard_markup.rs @@ -16,7 +16,7 @@ pub struct InlineKeyboardMarkup { /// /// Example: /// ``` -/// use async_telegram_bot::types::{ +/// use telebofr::types::{ /// InlineKeyboardButton, InlineKeyboardMarkup, /// }; /// From 873065a99b93a6e15325c0de3f454a8589fb557f Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Wed, 16 Oct 2019 11:55:41 +0600 Subject: [PATCH 05/66] Update README.md Related to https://github.com/telebofr/telebofr/issues/57. --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9f01fee6..98ecd769 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ <div align="center"> + <img src="ICON.png" width="300"/> <h1>telebofr</h1> + <hr> <a href="https://docs.rs/telebofr/"> <img src="https://img.shields.io/badge/docs.rs-link-blue.svg"> @@ -15,9 +17,5 @@ <img src="https://img.shields.io/badge/crates.io-v0.1.0-orange.svg"> </a> - <br> - <img src="ICON.png" width="300"/> - <br> - A full-featured framework that empowers you to easily build [Telegram bots](https://telegram.org/blog/bot-revolution) using the [`async`/`.await`](https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html) syntax in [Rust](https://www.rust-lang.org/). It handles all the difficult stuff so you can focus only on your business logic. </div> From e4da5214e05d44b792103767856a57e70600102e Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Wed, 16 Oct 2019 11:56:08 +0600 Subject: [PATCH 06/66] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 98ecd769..cf14abc4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ <div align="center"> <img src="ICON.png" width="300"/> <h1>telebofr</h1> - <hr> <a href="https://docs.rs/telebofr/"> <img src="https://img.shields.io/badge/docs.rs-link-blue.svg"> From 175e7572b224802500d3d907d9b04e7a5f42b460 Mon Sep 17 00:00:00 2001 From: Waffle <wafflewafflerov@gmail.com> Date: Wed, 16 Oct 2019 14:47:09 +0300 Subject: [PATCH 07/66] Add dispatcher trait --- src/dispatcher/mod.rs | 7 +++++++ src/dispatcher/simple/mod.rs | 22 ++++++++++++++++------ src/dispatcher/updater.rs | 12 ++++++++---- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/dispatcher/mod.rs b/src/dispatcher/mod.rs index b957411a..2011c220 100644 --- a/src/dispatcher/mod.rs +++ b/src/dispatcher/mod.rs @@ -7,3 +7,10 @@ pub mod updater; pub use filter::Filter; pub use handler::Handler; + +use async_trait::async_trait; + +#[async_trait(?Send)] +pub trait Dispatcher<'a, U> { + async fn dispatch(&'a mut self, updater: U); +} diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 63ce3a28..16b3d6f6 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -1,10 +1,14 @@ pub mod error_policy; +use futures::StreamExt; +use async_trait::async_trait; + use crate::{ dispatcher::{ filter::Filter, handler::Handler, updater::Updater, + simple::error_policy::ErrorPolicy, }, types::{ Update, @@ -15,10 +19,6 @@ use crate::{ }, }; -use futures::StreamExt; -use crate::dispatcher::simple::error_policy::ErrorPolicy; - - type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E> + 'a>)>; /// Dispatcher that dispatches updates from telegram. @@ -166,9 +166,9 @@ where } // TODO: Can someone simplify this? - pub async fn dispatch<U, UE>(&mut self, updates: U) + pub async fn dispatch<U>(&mut self, updates: U) where - U: Updater<UE> + 'a + U: Updater + 'a { updates.for_each(|res| { async { @@ -219,6 +219,16 @@ where } } +#[async_trait(?Send)] +impl<'a, U, E> crate::dispatcher::Dispatcher<'a, U> for Dispatcher<'a, E> +where + E: std::fmt::Debug, + U: Updater + 'a, +{ + async fn dispatch(&'a mut self, updater: U) { + Dispatcher::dispatch(self, updater).await + } +} #[cfg(test)] mod tests { diff --git a/src/dispatcher/updater.rs b/src/dispatcher/updater.rs index 8dd14da1..74b0164b 100644 --- a/src/dispatcher/updater.rs +++ b/src/dispatcher/updater.rs @@ -99,7 +99,9 @@ use crate::{ /// [GetUpdates]: crate::requests::GetUpdates /// [getting updates]: https://core.telegram.org/bots/api#getting-updates /// [wiki]: https://en.wikipedia.org/wiki/Push_technology#Long_polling -pub trait Updater<E>: Stream<Item=Result<Update, E>> {} +pub trait Updater: Stream<Item=Result<Update, <Self as Updater>::Error>> { + type Error; +} #[pin_project] pub struct StreamUpdater<S> { @@ -116,14 +118,16 @@ impl<S> StreamUpdater<S> { impl<S, E> Stream for StreamUpdater<S> where S: Stream<Item=Result<Update, E>> { type Item = Result<Update, E>; - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { self.project().stream.poll_next(cx) } } -impl<S, E> Updater<E> for StreamUpdater<S> where S: Stream<Item=Result<Update, E>> {} +impl<S, E> Updater for StreamUpdater<S> where S: Stream<Item=Result<Update, E>> { + type Error = E; +} -pub fn polling<'a>(bot: &'a Bot) -> impl Updater<RequestError> + 'a { +pub fn polling<'a>(bot: &'a Bot) -> impl Updater<Error = RequestError> + 'a { let stream = stream::unfold((bot, 0), |(bot, mut offset)| async move { // this match converts Result<Vec<_>, _> -> Vec<Result<_, _>> let updates = match bot.get_updates().offset(offset).send().await { From 5a399778c73614b3754c0d64ae5b84a1148bd9a6 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Wed, 16 Oct 2019 18:17:08 +0600 Subject: [PATCH 08/66] Update README.md Related to https://github.com/telebofr/telebofr/issues/57. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf14abc4..299433df 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ <div align="center"> - <img src="ICON.png" width="300"/> + <img src="ICON.png" width="200"/> <h1>telebofr</h1> <a href="https://docs.rs/telebofr/"> From 4ce7ceb8318cecf9d23852dc29a0fc19e12a4c98 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 10:36:30 +0600 Subject: [PATCH 09/66] Replace 'RequestContext' with 'Bot' --- src/bot/api.rs | 52 +++++++++++----------- src/bot/download.rs | 5 ++- src/bot/mod.rs | 14 +++--- src/dispatcher/simple/mod.rs | 2 +- src/dispatcher/updater.rs | 4 +- src/requests/answer_pre_checkout_query.rs | 13 +++--- src/requests/answer_shipping_query.rs | 13 +++--- src/requests/edit_message_live_location.rs | 13 +++--- src/requests/forward_message.rs | 13 +++--- src/requests/get_chat.rs | 9 ++-- src/requests/get_file.rs | 13 +++--- src/requests/get_me.rs | 11 ++--- src/requests/get_updates.rs | 13 +++--- src/requests/get_user_profile_photos.rs | 13 +++--- src/requests/kick_chat_member.rs | 13 +++--- src/requests/mod.rs | 12 +---- src/requests/pin_chat_message.rs | 13 +++--- src/requests/promote_chat_member.rs | 13 +++--- src/requests/restrict_chat_member.rs | 13 +++--- src/requests/send_animation.rs | 13 +++--- src/requests/send_audio.rs | 13 +++--- src/requests/send_chat_action.rs | 17 +++---- src/requests/send_contact.rs | 13 +++--- src/requests/send_document.rs | 13 +++--- src/requests/send_location.rs | 13 +++--- src/requests/send_media_group.rs | 13 +++--- src/requests/send_message.rs | 17 +++---- src/requests/send_photo.rs | 13 +++--- src/requests/send_poll.rs | 13 +++--- src/requests/send_venue.rs | 13 +++--- src/requests/send_video.rs | 13 +++--- src/requests/send_video_note.rs | 13 +++--- src/requests/send_voice.rs | 13 +++--- src/requests/stop_message_live_location.rs | 13 +++--- src/requests/unban_chat_member.rs | 13 +++--- src/requests/unpin_chat_message.rs | 13 +++--- 36 files changed, 247 insertions(+), 234 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index a75328c1..a74831d0 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,5 +1,4 @@ use crate::{ - bot::Bot, requests::{ AnswerPreCheckoutQuery, AnswerShippingQuery, EditMessageLiveLocation, ForwardMessage, GetFile, GetMe, KickChatMember, PinChatMessage, @@ -10,15 +9,16 @@ use crate::{ }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; +use crate::bot::Bot; /// Telegram functions impl Bot { pub fn get_me(&self) -> GetMe { - GetMe::new(self.ctx()) + GetMe::new(&self) } pub fn get_updates(&self) -> GetUpdates { - GetUpdates::new(self.ctx()) + GetUpdates::new(&self) } pub fn send_message<C, T>(&self, chat_id: C, text: T) -> SendMessage @@ -26,7 +26,7 @@ impl Bot { C: Into<ChatId>, T: Into<String>, { - SendMessage::new(self.ctx(), chat_id, text) + SendMessage::new(&self, chat_id, text) } pub fn edit_message_live_location<Lt, Lg>( @@ -38,7 +38,7 @@ impl Bot { Lt: Into<f64>, Lg: Into<f64>, { - EditMessageLiveLocation::new(self.ctx(), latitude, longitude) + EditMessageLiveLocation::new(&self, latitude, longitude) } pub fn forward_message<C, F, M>( @@ -52,7 +52,7 @@ impl Bot { F: Into<ChatId>, M: Into<i32>, { - ForwardMessage::new(self.ctx(), chat_id, from_chat_id, message_id) + ForwardMessage::new(&self, chat_id, from_chat_id, message_id) } pub fn send_audio<C, A>(&self, chat_id: C, audio: A) -> SendAudio @@ -60,7 +60,7 @@ impl Bot { C: Into<ChatId>, A: Into<InputFile>, { - SendAudio::new(self.ctx(), chat_id, audio) + SendAudio::new(&self, chat_id, audio) } pub fn send_location<C, Lt, Lg>( @@ -74,7 +74,7 @@ impl Bot { Lt: Into<f64>, Lg: Into<f64>, { - SendLocation::new(self.ctx(), chat_id, latitude, longitude) + SendLocation::new(&self, chat_id, latitude, longitude) } pub fn send_media_group<C, M>(&self, chat_id: C, media: M) -> SendMediaGroup @@ -82,7 +82,7 @@ impl Bot { C: Into<ChatId>, M: Into<Vec<InputMedia>>, { - SendMediaGroup::new(self.ctx(), chat_id, media) + SendMediaGroup::new(&self, chat_id, media) } pub fn send_photo<C, P>(&self, chat_id: C, photo: P) -> SendPhoto @@ -90,18 +90,18 @@ impl Bot { C: Into<ChatId>, P: Into<InputFile>, { - SendPhoto::new(self.ctx(), chat_id, photo) + SendPhoto::new(&self, chat_id, photo) } pub fn stop_message_live_location(&self) -> StopMessageLiveLocation { - StopMessageLiveLocation::new(self.ctx()) + StopMessageLiveLocation::new(&self) } pub fn get_file<F>(&self, file_id: F) -> GetFile where F: Into<String>, { - GetFile::new(self.ctx(), file_id) + GetFile::new(&self, file_id) } pub fn answer_pre_checkout_query<I, O>( @@ -113,7 +113,7 @@ impl Bot { I: Into<String>, O: Into<bool>, { - AnswerPreCheckoutQuery::new(self.ctx(), pre_checkout_query_id, ok) + AnswerPreCheckoutQuery::new(&self, pre_checkout_query_id, ok) } pub fn answer_shipping_query<I, O>( @@ -125,7 +125,7 @@ impl Bot { I: Into<String>, O: Into<bool>, { - AnswerShippingQuery::new(self.ctx(), shipping_query_id, ok) + AnswerShippingQuery::new(&self, shipping_query_id, ok) } pub fn kick_chat_member<C, U>( @@ -137,7 +137,7 @@ impl Bot { C: Into<ChatId>, U: Into<i32>, { - KickChatMember::new(self.ctx(), chat_id, user_id) + KickChatMember::new(&self, chat_id, user_id) } pub fn pin_chat_message<C, M>( @@ -149,7 +149,7 @@ impl Bot { C: Into<ChatId>, M: Into<i32>, { - PinChatMessage::new(self.ctx(), chat_id, message_id) + PinChatMessage::new(&self, chat_id, message_id) } pub fn promote_chat_member<C, U>( @@ -161,7 +161,7 @@ impl Bot { C: Into<ChatId>, U: Into<i32>, { - PromoteChatMember::new(self.ctx(), chat_id, user_id) + PromoteChatMember::new(&self, chat_id, user_id) } pub fn restrict_chat_member<C, U, P>( @@ -175,7 +175,7 @@ impl Bot { U: Into<i32>, P: Into<ChatPermissions>, { - RestrictChatMember::new(self.ctx(), chat_id, user_id, permissions) + RestrictChatMember::new(&self, chat_id, user_id, permissions) } pub fn send_chat_action<C, A>( @@ -187,7 +187,7 @@ impl Bot { C: Into<ChatId>, A: Into<ChatAction>, { - SendChatAction::new(self.ctx(), chat_id, action) + SendChatAction::new(&self, chat_id, action) } pub fn send_contact<C, P, F>( @@ -201,7 +201,7 @@ impl Bot { P: Into<String>, F: Into<String>, { - SendContact::new(self.ctx(), chat_id, phone_number, first_name) + SendContact::new(&self, chat_id, phone_number, first_name) } pub fn send_poll<C, Q, O>( @@ -215,7 +215,7 @@ impl Bot { Q: Into<String>, O: Into<Vec<String>>, { - SendPoll::new(self.ctx(), chat_id, question, options) + SendPoll::new(&self, chat_id, question, options) } pub fn send_venue<C, Lt, Lg, T, A>( @@ -233,7 +233,7 @@ impl Bot { T: Into<String>, A: Into<String>, { - SendVenue::new(self.ctx(), chat_id, latitude, longitude, title, address) + SendVenue::new(&self, chat_id, latitude, longitude, title, address) } pub fn send_video_note<C, V>( @@ -245,7 +245,7 @@ impl Bot { C: Into<ChatId>, V: Into<String>, // TODO: InputFile { - SendVideoNote::new(self.ctx(), chat_id, video_note) + SendVideoNote::new(&self, chat_id, video_note) } pub fn send_voice<C, V>(&self, chat_id: C, voice: V) -> SendVoice @@ -253,7 +253,7 @@ impl Bot { C: Into<ChatId>, V: Into<String>, // TODO: InputFile { - SendVoice::new(self.ctx(), chat_id, voice) + SendVoice::new(&self, chat_id, voice) } pub fn unban_chat_member<C, U>( @@ -265,13 +265,13 @@ impl Bot { C: Into<ChatId>, U: Into<i32>, { - UnbanChatMember::new(self.ctx(), chat_id, user_id) + UnbanChatMember::new(&self, chat_id, user_id) } pub fn unpin_chat_message<C>(&self, chat_id: C) -> UnpinChatMessage where C: Into<ChatId>, { - UnpinChatMessage::new(self.ctx(), chat_id) + UnpinChatMessage::new(&self, chat_id) } } diff --git a/src/bot/download.rs b/src/bot/download.rs index c6100791..9c11f376 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -5,7 +5,8 @@ use ::{bytes::Bytes, tokio::stream::Stream}; #[cfg(feature = "unstable-stream")] use crate::network::download_file_stream; -use crate::{bot::Bot, network::download_file, DownloadError}; +use crate::{network::download_file, DownloadError}; +use crate::bot::Bot; impl Bot { /// Download file from telegram into `destination`. @@ -17,7 +18,7 @@ impl Bot { /// /// ```no_run /// use telebofr::{ - /// bot::Bot, requests::Request, types::File as TgFile, + /// bot:: requests::Request, types::File as TgFile, /// }; /// use tokio::fs::File; /// # use telebofr::RequestError; diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 34020623..d4e6d884 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -2,11 +2,10 @@ use reqwest::Client; -use crate::requests::RequestContext; - mod api; mod download; +#[derive(Debug, Clone)] pub struct Bot { token: String, client: Client, @@ -30,10 +29,11 @@ impl Bot { } impl Bot { - fn ctx(&self) -> RequestContext { - RequestContext { - token: &self.token, - client: &self.client, - } + pub fn token(&self) -> &str { + &self.token + } + + pub fn client(&self) -> &Client { + &self.client } } diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 573b9d38..86a056e9 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -41,7 +41,7 @@ type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E /// # async fn run() { /// use std::convert::Infallible; /// use telebofr::{ -/// bot::Bot, +/// bot:: /// types::Message, /// dispatcher::{ /// updater::polling, diff --git a/src/dispatcher/updater.rs b/src/dispatcher/updater.rs index 74b0164b..29df78d8 100644 --- a/src/dispatcher/updater.rs +++ b/src/dispatcher/updater.rs @@ -7,10 +7,10 @@ use pin_project::pin_project; use futures::{Stream, StreamExt, stream}; use crate::{ - bot::Bot, types::Update, RequestError, }; +use crate::bot::Bot; // Currently just a placeholder, but I'll add here some methods /// Updater is stream of updates. @@ -148,4 +148,4 @@ pub fn polling<'a>(bot: &'a Bot) -> impl Updater<Error = RequestError> + 'a { // TODO implement webhook (this actually require webserver and probably we // should add cargo feature that adds webhook) -//pub fn webhook<'a>(bot: &'a Bot, cfg: WebhookConfig) -> Updater<impl Stream<Item=Result<Update, ???>> + 'a> {} +//pub fn webhook<'a>(bot: &'a cfg: WebhookConfig) -> Updater<impl Stream<Item=Result<Update, ???>> + 'a> {} diff --git a/src/requests/answer_pre_checkout_query.rs b/src/requests/answer_pre_checkout_query.rs index b7f5bfe1..289bad52 100644 --- a/src/requests/answer_pre_checkout_query.rs +++ b/src/requests/answer_pre_checkout_query.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::True, }; +use crate::bot::Bot; #[derive(Debug, Serialize, Clone)] /// Once the user has confirmed their payment and shipping details, the Bot API @@ -16,7 +17,7 @@ use crate::{ /// [`Update`]: crate::types::Update pub struct AnswerPreCheckoutQuery<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the query to be answered pub pre_checkout_query_id: String, @@ -48,8 +49,8 @@ impl Request for AnswerPreCheckoutQuery<'_> { impl AnswerPreCheckoutQuery<'_> { pub async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "answerPreCheckoutQuery", &self, ) @@ -59,7 +60,7 @@ impl AnswerPreCheckoutQuery<'_> { impl<'a> AnswerPreCheckoutQuery<'a> { pub(crate) fn new<S, B>( - ctx: RequestContext<'a>, + bot: &'a Bot, pre_checkout_query_id: S, ok: B, ) -> Self @@ -68,7 +69,7 @@ impl<'a> AnswerPreCheckoutQuery<'a> { B: Into<bool>, { Self { - ctx, + bot, pre_checkout_query_id: pre_checkout_query_id.into(), ok: ok.into(), error_message: None, diff --git a/src/requests/answer_shipping_query.rs b/src/requests/answer_shipping_query.rs index b7a25069..59d09cc9 100644 --- a/src/requests/answer_shipping_query.rs +++ b/src/requests/answer_shipping_query.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ShippingOption, True}, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// If you sent an invoice requesting a shipping address and the parameter @@ -15,7 +16,7 @@ use crate::{ /// [`Update`]: crate::types::Update pub struct AnswerShippingQuery<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the query to be answered pub shipping_query_id: String, @@ -49,8 +50,8 @@ impl Request for AnswerShippingQuery<'_> { impl AnswerShippingQuery<'_> { pub async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "answerShippingQuery", &self, ) @@ -60,7 +61,7 @@ impl AnswerShippingQuery<'_> { impl<'a> AnswerShippingQuery<'a> { pub(crate) fn new<S, B>( - ctx: RequestContext<'a>, + bot: &'a Bot, shipping_query_id: S, ok: B, ) -> Self @@ -69,7 +70,7 @@ impl<'a> AnswerShippingQuery<'a> { B: Into<bool>, { Self { - ctx, + bot, shipping_query_id: shipping_query_id.into(), ok: ok.into(), shipping_options: None, diff --git a/src/requests/edit_message_live_location.rs b/src/requests/edit_message_live_location.rs index c4c0fc4e..ddef8c11 100644 --- a/src/requests/edit_message_live_location.rs +++ b/src/requests/edit_message_live_location.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to edit live location messages. A location can be edited @@ -17,7 +18,7 @@ use crate::{ /// [`Message`]: crate::types::Message pub struct EditMessageLiveLocation<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, #[serde(skip_serializing_if = "Option::is_none")] /// Required if inline_message_id is not specified. Unique identifier for @@ -53,8 +54,8 @@ impl Request for EditMessageLiveLocation<'_> { impl EditMessageLiveLocation<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "editMessageLiveLocation", &self, ) @@ -64,7 +65,7 @@ impl EditMessageLiveLocation<'_> { impl<'a> EditMessageLiveLocation<'a> { pub(crate) fn new<Lt, Lg>( - ctx: RequestContext<'a>, + bot: &'a Bot, latitude: Lt, longitude: Lg, ) -> Self @@ -73,7 +74,7 @@ impl<'a> EditMessageLiveLocation<'a> { Lg: Into<f64>, { Self { - ctx, + bot, chat_id: None, message_id: None, inline_message_id: None, diff --git a/src/requests/forward_message.rs b/src/requests/forward_message.rs index 9c16ae67..f0b05a99 100644 --- a/src/requests/forward_message.rs +++ b/src/requests/forward_message.rs @@ -2,16 +2,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message}, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to forward messages of any kind. On success, the sent /// [`Message`] is returned. pub struct ForwardMessage<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) @@ -40,8 +41,8 @@ impl Request for ForwardMessage<'_> { impl ForwardMessage<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - self.ctx.client, - self.ctx.token, + self.bot.client(), + self.bot.token(), "forwardMessage", &self, ) @@ -51,7 +52,7 @@ impl ForwardMessage<'_> { impl<'a> ForwardMessage<'a> { pub(crate) fn new<C, Fc, M>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, from_chat_id: Fc, message_id: M, @@ -62,7 +63,7 @@ impl<'a> ForwardMessage<'a> { M: Into<i32>, { Self { - ctx, + bot, chat_id: chat_id.into(), from_chat_id: from_chat_id.into(), message_id: message_id.into(), diff --git a/src/requests/get_chat.rs b/src/requests/get_chat.rs index 7135f226..b1d0c70d 100644 --- a/src/requests/get_chat.rs +++ b/src/requests/get_chat.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{Chat, ChatId}, }; +use crate::bot::Bot; /// Use this method to get up to date information about the chat /// (current name of the user for one-on-one conversations, @@ -13,7 +14,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct GetChat<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username /// of the target supergroup or channel (in the format @channelusername) chat_id: ChatId, @@ -31,8 +32,8 @@ impl Request for GetChat<'_> { impl GetChat<'_> { pub async fn send(self) -> ResponseResult<Chat> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "getChat", &self, ) diff --git a/src/requests/get_file.rs b/src/requests/get_file.rs index 59785b17..3c55e7a4 100644 --- a/src/requests/get_file.rs +++ b/src/requests/get_file.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::File, }; +use crate::bot::Bot; /// Use this method to get basic info about a file and prepare it for /// downloading. For the moment, bots can download files of up to 20MB in size. @@ -16,7 +17,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct GetFile<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// File identifier to get info about pub file_id: String, } @@ -33,8 +34,8 @@ impl Request for GetFile<'_> { impl GetFile<'_> { pub async fn send(self) -> ResponseResult<File> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "getFile", &self, ) @@ -43,12 +44,12 @@ impl GetFile<'_> { } impl<'a> GetFile<'a> { - pub(crate) fn new<F>(ctx: RequestContext<'a>, value: F) -> Self + pub(crate) fn new<F>(bot: &'a Bot, value: F) -> Self where F: Into<String>, { Self { - ctx, + bot, file_id: value.into(), } } diff --git a/src/requests/get_me.rs b/src/requests/get_me.rs index 20cfa3ef..5ec4eed3 100644 --- a/src/requests/get_me.rs +++ b/src/requests/get_me.rs @@ -2,15 +2,16 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::User, }; +use crate::bot::Bot; #[derive(Debug, Clone)] /// A simple method for testing your bot's auth token. Requires no parameters. /// Returns basic information about the bot in form of a [`User`] object. pub struct GetMe<'a> { - ctx: RequestContext<'a>, + bot: &'a Bot, } #[async_trait] @@ -24,12 +25,12 @@ impl Request for GetMe<'_> { impl GetMe<'_> { pub async fn send(self) -> ResponseResult<User> { - network::request_simple(self.ctx.client, self.ctx.token, "getMe").await + network::request_simple(self.bot.client(), self.bot.token(), "getMe").await } } impl<'a> GetMe<'a> { - pub(crate) fn new(ctx: RequestContext<'a>) -> Self { - GetMe { ctx } + pub(crate) fn new(bot: &'a Bot) -> Self { + GetMe { bot } } } diff --git a/src/requests/get_updates.rs b/src/requests/get_updates.rs index 176a0e91..50f1dac1 100644 --- a/src/requests/get_updates.rs +++ b/src/requests/get_updates.rs @@ -2,14 +2,15 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::Update, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] pub struct GetUpdates<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, pub offset: Option<i32>, pub limit: Option<u8>, @@ -41,8 +42,8 @@ impl Request for GetUpdates<'_> { impl GetUpdates<'_> { pub async fn send(self) -> ResponseResult<Vec<Update>> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "getUpdates", &self, ) @@ -51,9 +52,9 @@ impl GetUpdates<'_> { } impl<'a> GetUpdates<'a> { - pub(crate) fn new(ctx: RequestContext<'a>) -> Self { + pub(crate) fn new(bot: &'a Bot) -> Self { Self { - ctx, + bot, offset: None, limit: None, timeout: None, diff --git a/src/requests/get_user_profile_photos.rs b/src/requests/get_user_profile_photos.rs index 6044441d..a66ff8ba 100644 --- a/src/requests/get_user_profile_photos.rs +++ b/src/requests/get_user_profile_photos.rs @@ -2,16 +2,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::UserProfilePhotos, }; +use crate::bot::Bot; ///Use this method to get a list of profile pictures for a user. Returns a /// UserProfilePhotos object. #[derive(Debug, Clone, Serialize)] pub struct GetUserProfilePhotos<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier of the target user pub user_id: i32, /// Sequential number of the first photo to be returned. By default, all @@ -36,8 +37,8 @@ impl Request for GetUserProfilePhotos<'_> { impl GetUserProfilePhotos<'_> { async fn send(self) -> ResponseResult<UserProfilePhotos> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "getUserProfilePhotos", &self, ) @@ -46,12 +47,12 @@ impl GetUserProfilePhotos<'_> { } impl<'a> GetUserProfilePhotos<'a> { - pub fn new<U>(ctx: RequestContext<'a>, user_id: U) -> Self + pub fn new<U>(bot: &'a Bot, user_id: U) -> Self where U: Into<i32>, { Self { - ctx, + bot, user_id: user_id.into(), offset: None, limit: None, diff --git a/src/requests/kick_chat_member.rs b/src/requests/kick_chat_member.rs index 9dec2cd6..8861031b 100644 --- a/src/requests/kick_chat_member.rs +++ b/src/requests/kick_chat_member.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; +use crate::bot::Bot; /// Use this method to kick a user from a group, a supergroup or a channel. In /// the case of supergroups and channels, the user will not be able to return to @@ -14,7 +15,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct KickChatMember<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target group or username of the target /// supergroup or channel (in the format @channelusername) pub chat_id: ChatId, @@ -39,8 +40,8 @@ impl Request for KickChatMember<'_> { impl KickChatMember<'_> { async fn send(self) -> ResponseResult<True> { network::request_json( - self.ctx.client, - self.ctx.token, + self.bot.client(), + self.bot.token(), "kickChatMember", &self, ) @@ -50,7 +51,7 @@ impl KickChatMember<'_> { impl<'a> KickChatMember<'a> { pub(crate) fn new<C, U>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, user_id: U, ) -> Self @@ -59,7 +60,7 @@ impl<'a> KickChatMember<'a> { U: Into<i32>, { Self { - ctx, + bot, chat_id: chat_id.into(), user_id: user_id.into(), until_date: None, diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 50f7ffaa..4940e317 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -1,6 +1,5 @@ //! Raw API functions. -use reqwest::Client; use serde::de::DeserializeOwned; use async_trait::async_trait; @@ -72,13 +71,4 @@ pub trait Request { /// Send this request. async fn send_boxed(self) -> ResponseResult<Self::Output>; -} - -/// A context used to send all the requests. -#[derive(Debug, Clone)] -pub struct RequestContext<'a> { - /// An HTTPS client. - pub client: &'a Client, - /// A token of your bot. - pub token: &'a str, -} +} \ No newline at end of file diff --git a/src/requests/pin_chat_message.rs b/src/requests/pin_chat_message.rs index 9033e4dd..c12e9e9e 100644 --- a/src/requests/pin_chat_message.rs +++ b/src/requests/pin_chat_message.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; +use crate::bot::Bot; /// Use this method to get up to date information about the chat /// (current name of the user for one-on-one conversations, @@ -13,7 +14,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct PinChatMessage<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username /// of the target supergroup or channel (in the format @channelusername) pub chat_id: ChatId, @@ -23,7 +24,7 @@ pub struct PinChatMessage<'a> { impl<'a> PinChatMessage<'a> { pub(crate) fn new<C, M>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, message_id: M, ) -> Self @@ -32,7 +33,7 @@ impl<'a> PinChatMessage<'a> { M: Into<i32>, { Self { - ctx, + bot, chat_id: chat_id.into(), message_id: message_id.into(), disable_notification: None, @@ -59,8 +60,8 @@ impl Request for PinChatMessage<'_> { impl PinChatMessage<'_> { async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "pinChatMessage", &self, ) diff --git a/src/requests/promote_chat_member.rs b/src/requests/promote_chat_member.rs index d6c47d9d..2a4ef01c 100644 --- a/src/requests/promote_chat_member.rs +++ b/src/requests/promote_chat_member.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; +use crate::bot::Bot; ///Use this method to promote or demote a user in a supergroup or a channel. /// The bot must be an administrator in the chat for this to work and must have @@ -13,7 +14,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct PromoteChatMember<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) pub chat_id: ChatId, @@ -62,8 +63,8 @@ impl Request for PromoteChatMember<'_> { impl PromoteChatMember<'_> { pub async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "promoteChatMember", &self, ) @@ -73,7 +74,7 @@ impl PromoteChatMember<'_> { impl<'a> PromoteChatMember<'a> { pub(crate) fn new<C, U>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, user_id: U, ) -> Self @@ -82,7 +83,7 @@ impl<'a> PromoteChatMember<'a> { U: Into<i32>, { Self { - ctx, + bot, chat_id: chat_id.into(), user_id: user_id.into(), can_change_info: None, diff --git a/src/requests/restrict_chat_member.rs b/src/requests/restrict_chat_member.rs index 5243484e..6941c14c 100644 --- a/src/requests/restrict_chat_member.rs +++ b/src/requests/restrict_chat_member.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, ChatPermissions, True}, }; +use crate::bot::Bot; /// Use this method to restrict a user in a supergroup. The bot must be an /// administrator in the supergroup for this to work and must have the @@ -13,7 +14,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct RestrictChatMember<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target chat or username of the target /// supergroup (in the format @supergroupusername) pub chat_id: ChatId, @@ -40,8 +41,8 @@ impl Request for RestrictChatMember<'_> { impl RestrictChatMember<'_> { async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "restrictChatMember", &self, ) @@ -51,7 +52,7 @@ impl RestrictChatMember<'_> { impl<'a> RestrictChatMember<'a> { pub(crate) fn new<C, U, P>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, user_id: U, permissions: P, @@ -62,7 +63,7 @@ impl<'a> RestrictChatMember<'a> { P: Into<ChatPermissions>, { Self { - ctx, + bot, chat_id: chat_id.into(), user_id: user_id.into(), permissions: permissions.into(), diff --git a/src/requests/send_animation.rs b/src/requests/send_animation.rs index 96b08299..89d70a58 100644 --- a/src/requests/send_animation.rs +++ b/src/requests/send_animation.rs @@ -1,8 +1,9 @@ use async_trait::async_trait; use crate::network; -use crate::requests::{Request, RequestContext, ResponseResult}; +use crate::requests::{Request, ResponseResult}; use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; +use crate::bot::Bot; ///TODO: add to bot api ///Use this method to send animation files (GIF or H.264/MPEG-4 AVC video @@ -12,7 +13,7 @@ use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; #[derive(Debug, Clone, Serialize)] pub struct SendAnimation<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) pub chat_id: ChatId, @@ -76,8 +77,8 @@ impl Request for SendAnimation<'_> { impl SendAnimation<'_> { async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendAnimation", &self, ) @@ -87,7 +88,7 @@ impl SendAnimation<'_> { impl<'a> SendAnimation<'a> { pub(crate) fn new<C, S>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, animation: S, ) -> Self @@ -96,7 +97,7 @@ impl<'a> SendAnimation<'a> { S: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), animation: animation.into(), duration: None, diff --git a/src/requests/send_audio.rs b/src/requests/send_audio.rs index 731f47ad..1eeb75e7 100644 --- a/src/requests/send_audio.rs +++ b/src/requests/send_audio.rs @@ -3,10 +3,11 @@ use async_trait::async_trait; use crate::{ network, requests::{ - form_builder::FormBuilder, Request, RequestContext, ResponseResult, + form_builder::FormBuilder, Request, ResponseResult, }, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, }; +use crate::bot::Bot; /// Use this method to send audio files, if you want Telegram clients to display /// them in the music player. Your audio must be in the .mp3 format. On success, @@ -18,7 +19,7 @@ use crate::{ /// [`Message`]: crate::types::Message /// [`SendVoice`]: crate::requests::SendVoice pub struct SendAudio<'a> { - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) @@ -88,8 +89,8 @@ impl SendAudio<'_> { network::request_multipart( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendAudio", params.build(), ) @@ -99,7 +100,7 @@ impl SendAudio<'_> { impl<'a> SendAudio<'a> { pub(crate) fn new<C, A>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, audio: A, ) -> Self @@ -108,7 +109,7 @@ impl<'a> SendAudio<'a> { A: Into<InputFile>, { Self { - ctx, + bot, chat_id: chat_id.into(), audio: audio.into(), caption: None, diff --git a/src/requests/send_chat_action.rs b/src/requests/send_chat_action.rs index 54e898bb..9ed0c511 100644 --- a/src/requests/send_chat_action.rs +++ b/src/requests/send_chat_action.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatAction, ChatId, True}, }; +use crate::bot::Bot; ///Use this method when you need to tell the user that something is happening /// on the bot's side. The status is set for 5 seconds or less (when a message @@ -13,7 +14,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct SendChatAction<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or /// username of the target channel (in the format @channelusername) pub chat_id: ChatId, @@ -37,8 +38,8 @@ impl Request for SendChatAction<'_> { impl SendChatAction<'_> { pub async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendChatAction", &self, ) @@ -47,17 +48,13 @@ impl SendChatAction<'_> { } impl<'a> SendChatAction<'a> { - pub(crate) fn new<Cid, Ca>( - ctx: RequestContext<'a>, - chat_id: Cid, - action: Ca, - ) -> Self + pub(crate) fn new<Cid, Ca>(bot: &'a Bot, chat_id: Cid, action: Ca,) -> Self where Cid: Into<ChatId>, Ca: Into<ChatAction>, { Self { - ctx, + bot, chat_id: chat_id.into(), action: action.into(), } diff --git a/src/requests/send_contact.rs b/src/requests/send_contact.rs index 307fb321..50df7b68 100644 --- a/src/requests/send_contact.rs +++ b/src/requests/send_contact.rs @@ -2,16 +2,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; +use crate::bot::Bot; /// Use this method to send phone contacts. /// returned. #[derive(Debug, Clone, Serialize)] pub struct SendContact<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or /// username of the target channel (in the format @channelusername) pub chat_id: ChatId, @@ -54,8 +55,8 @@ impl Request for SendContact<'_> { impl SendContact<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendContact", &self, ) @@ -65,7 +66,7 @@ impl SendContact<'_> { impl<'a> SendContact<'a> { pub(crate) fn new<C, P, F>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, phone_number: P, first_name: F, @@ -76,7 +77,7 @@ impl<'a> SendContact<'a> { F: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), phone_number: phone_number.into(), first_name: first_name.into(), diff --git a/src/requests/send_document.rs b/src/requests/send_document.rs index 298baa02..d1b88526 100644 --- a/src/requests/send_document.rs +++ b/src/requests/send_document.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, }; +use crate::bot::Bot; // TODO: add method to bot/api @@ -14,7 +15,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct SendDocument<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target /// channel (in the format @channelusername) pub chat_id: ChatId, @@ -69,8 +70,8 @@ impl Request for SendDocument<'_> { impl SendDocument<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendDocument", &self, ) @@ -80,7 +81,7 @@ impl SendDocument<'_> { impl<'a> SendDocument<'a> { pub(crate) fn new<C, D>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, document: D, ) -> Self @@ -89,7 +90,7 @@ impl<'a> SendDocument<'a> { D: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), document: document.into(), thumb: None, diff --git a/src/requests/send_location.rs b/src/requests/send_location.rs index a37162b2..708d5441 100644 --- a/src/requests/send_location.rs +++ b/src/requests/send_location.rs @@ -4,16 +4,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to send point on the map. On success, the sent [`Message`] /// is returned. pub struct SendLocation<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) @@ -50,8 +51,8 @@ impl Request for SendLocation<'_> { impl SendLocation<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendLocation", &self, ) @@ -61,7 +62,7 @@ impl SendLocation<'_> { impl<'a> SendLocation<'a> { pub(crate) fn new<Lt, Lg, C>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, latitude: Lt, longitude: Lg, @@ -72,7 +73,7 @@ impl<'a> SendLocation<'a> { C: Into<ChatId>, { Self { - ctx, + bot, chat_id: chat_id.into(), latitude: latitude.into(), longitude: longitude.into(), diff --git a/src/requests/send_media_group.rs b/src/requests/send_media_group.rs index d189a926..c3e9ea8a 100644 --- a/src/requests/send_media_group.rs +++ b/src/requests/send_media_group.rs @@ -3,15 +3,16 @@ use async_trait::async_trait; use crate::{ network::request_multipart, requests::{ - form_builder::FormBuilder, Request, RequestContext, ResponseResult, + form_builder::FormBuilder, Request, ResponseResult, }, types::{ChatId, InputMedia, Message, InputFile}, }; +use crate::bot::Bot; /// Use this method to send a group of photos or videos as an album. #[derive(Debug, Clone)] pub struct SendMediaGroup<'a> { - ctx: RequestContext<'a>, + bot: &'a Bot, pub chat_id: ChatId, pub media: Vec<InputMedia>, @@ -46,8 +47,8 @@ impl SendMediaGroup<'_> { ); request_multipart( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendMediaGroup", form.build(), ) @@ -57,7 +58,7 @@ impl SendMediaGroup<'_> { impl<'a> SendMediaGroup<'a> { pub(crate) fn new<C, M>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, media: M, ) -> Self @@ -66,7 +67,7 @@ impl<'a> SendMediaGroup<'a> { M: Into<Vec<InputMedia>>, { SendMediaGroup { - ctx, + bot, chat_id: chat_id.into(), media: media.into(), disable_notification: None, diff --git a/src/requests/send_message.rs b/src/requests/send_message.rs index adca7c4f..26c09ced 100644 --- a/src/requests/send_message.rs +++ b/src/requests/send_message.rs @@ -2,16 +2,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to send text messages. On success, the sent [`Message`] is /// returned. pub struct SendMessage<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) @@ -55,8 +56,8 @@ impl Request for SendMessage<'_> { impl SendMessage<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - self.ctx.client, - self.ctx.token, + self.bot.client(), + self.bot.token(), "sendMessage", &self, ) @@ -65,17 +66,13 @@ impl SendMessage<'_> { } impl<'a> SendMessage<'a> { - pub(crate) fn new<C, S>( - ctx: RequestContext<'a>, - chat_id: C, - text: S, - ) -> Self + pub(crate) fn new<C, S>(bot: &'a Bot, chat_id: C, text: S,) -> Self where C: Into<ChatId>, S: Into<String>, { SendMessage { - ctx, + bot, chat_id: chat_id.into(), text: text.into(), parse_mode: None, diff --git a/src/requests/send_photo.rs b/src/requests/send_photo.rs index 8092a55a..64f862b6 100644 --- a/src/requests/send_photo.rs +++ b/src/requests/send_photo.rs @@ -3,16 +3,17 @@ use async_trait::async_trait; use crate::{ network, requests::{ - form_builder::FormBuilder, Request, RequestContext, ResponseResult, + form_builder::FormBuilder, Request, ResponseResult, }, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, }; +use crate::bot::Bot; #[derive(Debug, Clone)] /// Use this method to send photos. On success, the sent [`Message`] is /// returned. pub struct SendPhoto<'a> { - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) @@ -64,8 +65,8 @@ impl SendPhoto<'_> { .add("photo", self.photo); network::request_multipart( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendPhoto", params.build(), ) @@ -75,7 +76,7 @@ impl SendPhoto<'_> { impl<'a> SendPhoto<'a> { pub(crate) fn new<C, P>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, photo: P, ) -> Self @@ -84,7 +85,7 @@ impl<'a> SendPhoto<'a> { P: Into<InputFile>, { Self { - ctx, + bot, chat_id: chat_id.into(), photo: photo.into(), caption: None, diff --git a/src/requests/send_poll.rs b/src/requests/send_poll.rs index 9d8466d3..f138ef7b 100644 --- a/src/requests/send_poll.rs +++ b/src/requests/send_poll.rs @@ -2,16 +2,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; +use crate::bot::Bot; /// Use this method to send a native poll. A native poll can't be sent to a /// private chat. On success, the sent Message is returned. #[derive(Debug, Clone, Serialize)] pub struct SendPoll<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// identifier for the target chat or username of the target channel (in /// the format @channelusername). A native poll can't be sent to a private /// chat. @@ -44,8 +45,8 @@ impl Request for SendPoll<'_> { impl SendPoll<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendPoll", &self, ) @@ -55,7 +56,7 @@ impl SendPoll<'_> { impl<'a> SendPoll<'a> { pub(crate) fn new<C, Q, O>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, question: Q, options: O, @@ -66,7 +67,7 @@ impl<'a> SendPoll<'a> { O: Into<Vec<String>>, { Self { - ctx, + bot, chat_id: chat_id.into(), question: question.into(), options: options.into(), diff --git a/src/requests/send_venue.rs b/src/requests/send_venue.rs index 6fdd45e7..59fa872e 100644 --- a/src/requests/send_venue.rs +++ b/src/requests/send_venue.rs @@ -2,16 +2,17 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; +use crate::bot::Bot; /// Use this method to send information about a venue. /// Message is returned. #[derive(Debug, Clone, Serialize)] pub struct SendVenue<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or /// username of the target channel (in the format @channelusername) pub chat_id: ChatId, @@ -59,8 +60,8 @@ impl Request for SendVenue<'_> { impl SendVenue<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendVenue", &self, ) @@ -70,7 +71,7 @@ impl SendVenue<'_> { impl<'a> SendVenue<'a> { pub(crate) fn new<Lt, Lg, C, T, A>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, latitude: Lt, longitude: Lg, @@ -85,7 +86,7 @@ impl<'a> SendVenue<'a> { A: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), latitude: latitude.into(), longitude: longitude.into(), diff --git a/src/requests/send_video.rs b/src/requests/send_video.rs index 5d8d6696..9d08e67f 100644 --- a/src/requests/send_video.rs +++ b/src/requests/send_video.rs @@ -1,8 +1,9 @@ use async_trait::async_trait; use crate::network; -use crate::requests::{Request, RequestContext, ResponseResult}; +use crate::requests::{Request, ResponseResult}; use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; +use crate::bot::Bot; //TODO: add action to bot api ///Use this method to send video files, Telegram clients support mp4 videos @@ -12,7 +13,7 @@ use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; #[derive(Debug, Clone, Serialize)] pub struct SendVideo<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) pub chat_id: ChatId, @@ -78,8 +79,8 @@ impl Request for SendVideo<'_> { impl SendVideo<'_> { async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendVideo", &self, ) @@ -89,7 +90,7 @@ impl SendVideo<'_> { impl<'a> SendVideo<'a> { pub(crate) fn new<C, V>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, video: V, ) -> Self @@ -98,7 +99,7 @@ impl<'a> SendVideo<'a> { V: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), video: video.into(), duration: None, diff --git a/src/requests/send_video_note.rs b/src/requests/send_video_note.rs index c824bfdf..89e304e7 100644 --- a/src/requests/send_video_note.rs +++ b/src/requests/send_video_note.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; +use crate::bot::Bot; ///As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 /// minute long. Use this method to send video messages. On success, the sent @@ -12,7 +13,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct SendVideoNote<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) pub chat_id: ChatId, @@ -65,8 +66,8 @@ impl Request for SendVideoNote<'_> { impl SendVideoNote<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendVideoNote", &self, ) @@ -76,7 +77,7 @@ impl SendVideoNote<'_> { impl<'a> SendVideoNote<'a> { pub(crate) fn new<C, V>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, video_note: V, ) -> Self @@ -85,7 +86,7 @@ impl<'a> SendVideoNote<'a> { V: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), video_note: video_note.into(), duration: None, diff --git a/src/requests/send_voice.rs b/src/requests/send_voice.rs index 75f139ea..d594fd7a 100644 --- a/src/requests/send_voice.rs +++ b/src/requests/send_voice.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, }; +use crate::bot::Bot; ///Use this method to send audio files, if you want Telegram clients to display /// the file as a playable voice message. For this to work, your audio must be @@ -15,7 +16,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct SendVoice<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) pub chat_id: ChatId, @@ -62,8 +63,8 @@ impl Request for SendVoice<'_> { impl SendVoice<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "sendVoice", &self, ) @@ -73,7 +74,7 @@ impl SendVoice<'_> { impl<'a> SendVoice<'a> { pub(crate) fn new<C, V>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, voice: V, ) -> Self @@ -82,7 +83,7 @@ impl<'a> SendVoice<'a> { V: Into<String>, { Self { - ctx, + bot, chat_id: chat_id.into(), voice: voice.into(), caption: None, diff --git a/src/requests/stop_message_live_location.rs b/src/requests/stop_message_live_location.rs index 5455944e..976cd6fc 100644 --- a/src/requests/stop_message_live_location.rs +++ b/src/requests/stop_message_live_location.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, InlineKeyboardMarkup, Message}, }; +use crate::bot::Bot; /// Use this method to stop updating a live location message before live_period /// expires. On success, if the message was sent by the bot, the sent Message is @@ -12,7 +13,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct StopMessageLiveLocation<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, /// Required if inline_message_id is not specified. Unique identifier for /// the target chat or username of the target channel (in the format /// @channelusername) @@ -44,8 +45,8 @@ impl Request for StopMessageLiveLocation<'_> { impl StopMessageLiveLocation<'_> { pub async fn send(self) -> ResponseResult<Message> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "stopMessageLiveLocation", &self, ) @@ -54,9 +55,9 @@ impl StopMessageLiveLocation<'_> { } impl<'a> StopMessageLiveLocation<'a> { - pub(crate) fn new(ctx: RequestContext<'a>) -> Self { + pub(crate) fn new(bot: &'a Bot) -> Self { Self { - ctx, + bot, chat_id: None, message_id: None, inline_message_id: None, diff --git a/src/requests/unban_chat_member.rs b/src/requests/unban_chat_member.rs index fb772d0d..b015e800 100644 --- a/src/requests/unban_chat_member.rs +++ b/src/requests/unban_chat_member.rs @@ -2,9 +2,10 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::ChatId, }; +use crate::bot::Bot; /// Use this method to unban a previously kicked user in a supergroup or /// channel. The user will not return to the group or channel automatically, but @@ -13,7 +14,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct UnbanChatMember<'a> { #[serde(skip_serializing)] - ctx: RequestContext<'a>, + bot: &'a Bot, ///Unique identifier for the target group or username of the target /// supergroup or channel (in the format @channelusername) pub chat_id: ChatId, @@ -33,8 +34,8 @@ impl Request for UnbanChatMember<'_> { impl UnbanChatMember<'_> { pub async fn send(self) -> ResponseResult<bool> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "unbanChatMember", &self, ) @@ -44,7 +45,7 @@ impl UnbanChatMember<'_> { impl<'a> UnbanChatMember<'a> { pub(crate) fn new<C, U>( - ctx: RequestContext<'a>, + bot: &'a Bot, chat_id: C, user_id: U, ) -> Self @@ -53,7 +54,7 @@ impl<'a> UnbanChatMember<'a> { U: Into<i32>, { Self { - ctx, + bot, chat_id: chat_id.into(), user_id: user_id.into(), } diff --git a/src/requests/unpin_chat_message.rs b/src/requests/unpin_chat_message.rs index 6bde53d0..ac98e34a 100644 --- a/src/requests/unpin_chat_message.rs +++ b/src/requests/unpin_chat_message.rs @@ -2,14 +2,15 @@ use async_trait::async_trait; use crate::{ network, - requests::{Request, RequestContext, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; +use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] pub struct UnpinChatMessage<'a> { #[serde(skip_serializing)] - pub ctx: RequestContext<'a>, + pub bot: &'a Bot, pub chat_id: ChatId, } @@ -26,8 +27,8 @@ impl Request for UnpinChatMessage<'_> { impl UnpinChatMessage<'_> { pub async fn send(self) -> ResponseResult<True> { network::request_json( - &self.ctx.client, - &self.ctx.token, + self.bot.client(), + self.bot.token(), "unpinChatMessage", &self, ) @@ -36,12 +37,12 @@ impl UnpinChatMessage<'_> { } impl<'a> UnpinChatMessage<'a> { - pub(crate) fn new<C>(ctx: RequestContext<'a>, value: C) -> Self + pub(crate) fn new<C>(bot: &'a Bot, value: C) -> Self where C: Into<ChatId>, { Self { - ctx, + bot, chat_id: value.into(), } } From 9b8f180a8ac6e21fd6d683a1e622b17ae373db6a Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 10:37:37 +0600 Subject: [PATCH 10/66] Format the sources --- src/bot/api.rs | 12 +- src/bot/download.rs | 6 +- src/dispatcher/filter.rs | 37 +-- src/dispatcher/handler.rs | 13 +- src/dispatcher/mod.rs | 11 +- src/dispatcher/simple/error_policy.rs | 12 +- src/dispatcher/simple/mod.rs | 227 ++++++++++------- src/dispatcher/updater.rs | 63 +++-- src/network/request.rs | 8 +- src/requests/answer_pre_checkout_query.rs | 2 +- src/requests/answer_shipping_query.rs | 10 +- src/requests/edit_message_live_location.rs | 10 +- src/requests/form_builder.rs | 11 +- src/requests/forward_message.rs | 4 +- src/requests/get_chat.rs | 4 +- src/requests/get_file.rs | 4 +- src/requests/get_me.rs | 7 +- src/requests/get_updates.rs | 4 +- src/requests/get_user_profile_photos.rs | 4 +- src/requests/kick_chat_member.rs | 10 +- src/requests/mod.rs | 2 +- src/requests/pin_chat_message.rs | 10 +- src/requests/promote_chat_member.rs | 10 +- src/requests/restrict_chat_member.rs | 4 +- src/requests/send_animation.rs | 12 +- src/requests/send_audio.rs | 13 +- src/requests/send_chat_action.rs | 6 +- src/requests/send_contact.rs | 4 +- src/requests/send_document.rs | 10 +- src/requests/send_location.rs | 4 +- src/requests/send_media_group.rs | 31 ++- src/requests/send_message.rs | 6 +- src/requests/send_photo.rs | 12 +- src/requests/send_poll.rs | 4 +- src/requests/send_venue.rs | 4 +- src/requests/send_video.rs | 12 +- src/requests/send_video_note.rs | 10 +- src/requests/send_voice.rs | 10 +- src/requests/stop_message_live_location.rs | 4 +- src/requests/unban_chat_member.rs | 10 +- src/requests/unpin_chat_message.rs | 4 +- src/types/inline_keyboard_markup.rs | 4 +- src/types/message.rs | 276 ++++++++++++++------- 43 files changed, 519 insertions(+), 402 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index a74831d0..01b4d8ff 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,15 +1,15 @@ +use crate::bot::Bot; use crate::{ requests::{ AnswerPreCheckoutQuery, AnswerShippingQuery, EditMessageLiveLocation, - ForwardMessage, GetFile, GetMe, KickChatMember, PinChatMessage, - PromoteChatMember, RestrictChatMember, SendAudio, SendChatAction, - SendContact, SendLocation, SendMediaGroup, SendMessage, SendPhoto, - SendPoll, SendVenue, SendVideoNote, SendVoice, StopMessageLiveLocation, - UnbanChatMember, UnpinChatMessage, GetUpdates + ForwardMessage, GetFile, GetMe, GetUpdates, KickChatMember, + PinChatMessage, PromoteChatMember, RestrictChatMember, SendAudio, + SendChatAction, SendContact, SendLocation, SendMediaGroup, SendMessage, + SendPhoto, SendPoll, SendVenue, SendVideoNote, SendVoice, + StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; -use crate::bot::Bot; /// Telegram functions impl Bot { diff --git a/src/bot/download.rs b/src/bot/download.rs index 9c11f376..4488e3b5 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -3,10 +3,10 @@ use tokio::io::AsyncWrite; #[cfg(feature = "unstable-stream")] use ::{bytes::Bytes, tokio::stream::Stream}; +use crate::bot::Bot; #[cfg(feature = "unstable-stream")] use crate::network::download_file_stream; use crate::{network::download_file, DownloadError}; -use crate::bot::Bot; impl Bot { /// Download file from telegram into `destination`. @@ -17,9 +17,7 @@ impl Bot { /// ## Examples /// /// ```no_run - /// use telebofr::{ - /// bot:: requests::Request, types::File as TgFile, - /// }; + /// use telebofr::{bot::requests::Request, types::File as TgFile}; /// use tokio::fs::File; /// # use telebofr::RequestError; /// diff --git a/src/dispatcher/filter.rs b/src/dispatcher/filter.rs index d5afadf5..bcb59f16 100644 --- a/src/dispatcher/filter.rs +++ b/src/dispatcher/filter.rs @@ -28,7 +28,9 @@ impl<T, F: Fn(&T) -> bool> Filter<T> for F { /// assert_eq!(false.test(&()), false); /// ``` impl<T> Filter<T> for bool { - fn test(&self, _: &T) -> bool { *self } + fn test(&self, _: &T) -> bool { + *self + } } /// And filter. @@ -82,7 +84,6 @@ pub fn and<A, B>(a: A, b: B) -> And<A, B> { And::new(a, b) } - /// Or filter. /// /// Passes if at least one underlying filters passes. @@ -92,7 +93,7 @@ pub fn and<A, B>(a: A, b: B) -> And<A, B> { /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{Or, Filter}; +/// use telebofr::dispatcher::filter::{Filter, Or}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Or::new(true, false).test(&())); @@ -134,14 +135,13 @@ pub fn or<A, B>(a: A, b: B) -> Or<A, B> { Or::new(a, b) } - /// Not filter. /// /// Passes if underlying filter don't pass. /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{Not, Filter}; +/// use telebofr::dispatcher::filter::{Filter, Not}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Not::new(false).test(&())); @@ -242,12 +242,11 @@ macro_rules! any { }; } - /// Simple wrapper around `Filter` that adds `|` and `&` operators. /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{Filter, f, F, And, Or}; +/// use telebofr::dispatcher::filter::{f, And, Filter, Or, F}; /// /// let flt1 = |i: &i32| -> bool { *i > 17 }; /// let flt2 = |i: &i32| -> bool { *i < 42 }; @@ -259,7 +258,6 @@ macro_rules! any { /// assert_eq!(and.test(&50), false); // `flt2` doesn't pass /// assert_eq!(and.test(&16), false); // `flt1` doesn't pass /// -/// /// let or = f(flt1) | flt3; /// assert!(or.test(&19)); // `flt1` passes /// assert!(or.test(&16)); // `flt2` passes @@ -267,9 +265,8 @@ macro_rules! any { /// /// assert_eq!(or.test(&17), false); // both don't pass /// -/// /// // Note: only first filter in chain should be wrapped in `f(...)` -/// let complicated: F<Or<And<_, _>, _>>= f(flt1) & flt2 | flt3; +/// let complicated: F<Or<And<_, _>, _>> = f(flt1) & flt2 | flt3; /// assert!(complicated.test(&2)); // `flt3` passes /// assert!(complicated.test(&21)); // `flt1` and `flt2` pass /// @@ -287,7 +284,7 @@ pub fn f<A>(a: A) -> F<A> { impl<T, A> Filter<T> for F<A> where - A: Filter<T> + A: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) @@ -310,8 +307,9 @@ impl<A, B> std::ops::BitOr<B> for F<A> { } } +/* workaround for `E0207` compiler error */ /// Extensions for filters -pub trait FilterExt<T /* workaround for `E0207` compiler error */> { +pub trait FilterExt<T> { /// Alias for [`Not::new`] /// /// ## Examples @@ -325,7 +323,10 @@ pub trait FilterExt<T /* workaround for `E0207` compiler error */> { /// ``` /// /// [`Not::new`]: crate::dispatcher::filter::Not::new - fn not(self) -> Not<Self> where Self: Sized { + fn not(self) -> Not<Self> + where + Self: Sized, + { Not::new(self) } @@ -344,7 +345,10 @@ pub trait FilterExt<T /* workaround for `E0207` compiler error */> { /// ``` /// /// [`Not::new`]: crate::dispatcher::filter::And::new - fn and<B>(self, other: B) -> And<Self, B> where Self: Sized { + fn and<B>(self, other: B) -> And<Self, B> + where + Self: Sized, + { And::new(self, other) } @@ -363,7 +367,10 @@ pub trait FilterExt<T /* workaround for `E0207` compiler error */> { /// ``` /// /// [`Not::new`]: crate::dispatcher::filter::Or::new - fn or<B>(self, other: B) -> Or<Self, B> where Self: Sized { + fn or<B>(self, other: B) -> Or<Self, B> + where + Self: Sized, + { Or::new(self, other) } } diff --git a/src/dispatcher/handler.rs b/src/dispatcher/handler.rs index 7c52928b..6a456a8e 100644 --- a/src/dispatcher/handler.rs +++ b/src/dispatcher/handler.rs @@ -1,12 +1,16 @@ -use futures::FutureExt; use std::future::Future; use std::pin::Pin; +use futures::FutureExt; + pub type HandlerResult<E> = Result<(), E>; /// Asynchronous handler for event `T` (like `&self, I -> Future` fn) pub trait Handler<'a, T, E> { - fn handle(&self, value: T) -> Pin<Box<dyn Future<Output = HandlerResult<E>> + 'a>>; + fn handle( + &self, + value: T, + ) -> Pin<Box<dyn Future<Output = HandlerResult<E>> + 'a>>; } pub trait IntoHandlerResult<E> { @@ -32,7 +36,10 @@ where R: IntoHandlerResult<E> + 'a, E: 'a, { - fn handle(&self, value: T) -> Pin<Box<dyn Future<Output = HandlerResult<E>> + 'a>> { + fn handle( + &self, + value: T, + ) -> Pin<Box<dyn Future<Output = HandlerResult<E>> + 'a>> { Box::pin(self(value).map(IntoHandlerResult::into_hr)) } } diff --git a/src/dispatcher/mod.rs b/src/dispatcher/mod.rs index 2011c220..06f2471d 100644 --- a/src/dispatcher/mod.rs +++ b/src/dispatcher/mod.rs @@ -1,16 +1,15 @@ //! Update dispatching. +use async_trait::async_trait; +pub use filter::Filter; +pub use handler::Handler; + pub mod filter; pub mod handler; pub mod simple; pub mod updater; -pub use filter::Filter; -pub use handler::Handler; - -use async_trait::async_trait; - -#[async_trait(?Send)] +#[async_trait(? Send)] pub trait Dispatcher<'a, U> { async fn dispatch(&'a mut self, updater: U); } diff --git a/src/dispatcher/simple/error_policy.rs b/src/dispatcher/simple/error_policy.rs index d71b254b..676d561f 100644 --- a/src/dispatcher/simple/error_policy.rs +++ b/src/dispatcher/simple/error_policy.rs @@ -1,6 +1,6 @@ -use std::pin::Pin; -use std::future::Future; use std::fmt::Debug; +use std::future::Future; +use std::pin::Pin; // TODO: shouldn't it be trait? pub enum ErrorPolicy<'a, E> { @@ -15,14 +15,12 @@ where { pub async fn handle_error(&self, error: E) { match self { - Self::Ignore => {}, + Self::Ignore => {} Self::Log => { // TODO: better message log::error!("Error in handler: {:?}", error) } - Self::Custom(func) => { - func(error).await - } + Self::Custom(func) => func(error).await, } } @@ -33,4 +31,4 @@ where { Self::Custom(Box::new(move |e| Box::pin(f(e)))) } -} \ No newline at end of file +} diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 86a056e9..99c66e28 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -1,25 +1,19 @@ -pub mod error_policy; - use futures::StreamExt; + use async_trait::async_trait; use crate::{ dispatcher::{ - filter::Filter, - handler::Handler, + filter::Filter, handler::Handler, simple::error_policy::ErrorPolicy, updater::Updater, - simple::error_policy::ErrorPolicy, - }, - types::{ - Update, - Message, - UpdateKind, - CallbackQuery, - ChosenInlineResult, }, + types::{CallbackQuery, ChosenInlineResult, Message, Update, UpdateKind}, }; -type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E> + 'a>)>; +pub mod error_policy; + +type Handlers<'a, T, E> = + Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E> + 'a>)>; /// Dispatcher that dispatches updates from telegram. /// @@ -29,10 +23,10 @@ type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E /// - Handler's fututres are also boxed /// - [Custom error policy] is also boxed /// - All errors from [updater] are ignored (TODO: remove this limitation) -/// - All handlers executed in order (this means that in dispatcher have -/// 2 upadtes it will first execute some handler into complition with -/// first update and **then** search for handler for second update, -/// this is probably wrong) +/// - All handlers executed in order (this means that in dispatcher have 2 +/// upadtes it will first execute some handler into complition with first +/// update and **then** search for handler for second update, this is probably +/// wrong) /// /// ## Examples /// @@ -41,11 +35,10 @@ type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E /// # async fn run() { /// use std::convert::Infallible; /// use telebofr::{ -/// bot:: -/// types::Message, +/// bot::types::Message, /// dispatcher::{ +/// simple::{error_policy::ErrorPolicy, Dispatcher}, /// updater::polling, -/// simple::{Dispatcher, error_policy::ErrorPolicy}, /// }, /// }; /// @@ -59,8 +52,8 @@ type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E /// // with error policy that just ignores all errors (that can't ever happen) /// let mut dp = Dispatcher::<Infallible>::new(ErrorPolicy::Ignore) /// // Add 'handler' that will handle all messages sent to the bot -/// .message_handler(true, |mes: Message| async move { -/// println!("New message: {:?}", mes) +/// .message_handler(true, |mes: Message| { +/// async move { println!("New message: {:?}", mes) } /// }) /// // Add 'handler' that will handle all /// // messages edited in chat with the bot @@ -72,8 +65,9 @@ type Handlers<'a, T, E> = Vec<(Box<dyn Filter<T> + 'a>, Box<dyn Handler<'a, T, E /// ``` /// /// [`std::fmt::Debug`]: std::fmt::Debug -/// [Custom error policy]: crate::dispatcher::simple::error_policy::ErrorPolicy::Custom -/// [updater]: crate::dispatcher::updater +/// [Custom error policy]: +/// crate::dispatcher::simple::error_policy::ErrorPolicy::Custom [updater]: +/// crate::dispatcher::updater pub struct Dispatcher<'a, E> { message_handlers: Handlers<'a, Message, E>, edited_message_handlers: Handlers<'a, Message, E>, @@ -98,7 +92,7 @@ where inline_query_handlers: Vec::new(), chosen_inline_result_handlers: Vec::new(), callback_query_handlers: Vec::new(), - error_policy + error_policy, } } @@ -107,7 +101,8 @@ where F: Filter<Message> + 'a, H: Handler<'a, Message, E> + 'a, { - self.message_handlers.push((Box::new(filter), Box::new(handler))); + self.message_handlers + .push((Box::new(filter), Box::new(handler))); self } @@ -116,7 +111,8 @@ where F: Filter<Message> + 'a, H: Handler<'a, Message, E> + 'a, { - self.edited_message_handlers.push((Box::new(filter), Box::new(handler))); + self.edited_message_handlers + .push((Box::new(filter), Box::new(handler))); self } @@ -125,16 +121,22 @@ where F: Filter<Message> + 'a, H: Handler<'a, Message, E> + 'a, { - self.channel_post_handlers.push((Box::new(filter), Box::new(handler))); + self.channel_post_handlers + .push((Box::new(filter), Box::new(handler))); self } - pub fn edited_channel_post_handler<F, H>(mut self, filter: F, handler: H) -> Self + pub fn edited_channel_post_handler<F, H>( + mut self, + filter: F, + handler: H, + ) -> Self where F: Filter<Message> + 'a, H: Handler<'a, Message, E> + 'a, { - self.edited_channel_post_handlers.push((Box::new(filter), Box::new(handler))); + self.edited_channel_post_handlers + .push((Box::new(filter), Box::new(handler))); self } @@ -143,16 +145,22 @@ where F: Filter<()> + 'a, H: Handler<'a, (), E> + 'a, { - self.inline_query_handlers.push((Box::new(filter), Box::new(handler))); + self.inline_query_handlers + .push((Box::new(filter), Box::new(handler))); self } - pub fn chosen_inline_result_handler<F, H>(mut self, filter: F, handler: H) -> Self + pub fn chosen_inline_result_handler<F, H>( + mut self, + filter: F, + handler: H, + ) -> Self where F: Filter<ChosenInlineResult> + 'a, H: Handler<'a, ChosenInlineResult, E> + 'a, { - self.chosen_inline_result_handlers.push((Box::new(filter), Box::new(handler))); + self.chosen_inline_result_handlers + .push((Box::new(filter), Box::new(handler))); self } @@ -161,65 +169,91 @@ where F: Filter<CallbackQuery> + 'a, H: Handler<'a, CallbackQuery, E> + 'a, { - self.callback_query_handlers.push((Box::new(filter), Box::new(handler))); + self.callback_query_handlers + .push((Box::new(filter), Box::new(handler))); self } // TODO: Can someone simplify this? pub async fn dispatch<U>(&mut self, updates: U) where - U: Updater + 'a + U: Updater + 'a, { - updates.for_each(|res| { - async { - let res = res; - let Update { kind, id } = match res { - Ok(upd) => upd, - _ => return // TODO: proper error handling - }; + updates + .for_each(|res| { + async { + let res = res; + let Update { kind, id } = match res { + Ok(upd) => upd, + _ => return, // TODO: proper error handling + }; - log::debug!("Handled update#{id:?}: {kind:?}", id = id, kind = kind); + log::debug!( + "Handled update#{id:?}: {kind:?}", + id = id, + kind = kind + ); - // TODO: can someone extract this to a function? - macro_rules! call { - ($h:expr, $value:expr) => {{ - let value = $value; - let handler = $h.iter().find_map(|e| { - let (filter, handler) = e; - if filter.test(&value) { - Some(handler) - } else { - None + // TODO: can someone extract this to a function? + macro_rules! call { + ($h:expr, $value:expr) => {{ + let value = $value; + let handler = $h.iter().find_map(|e| { + let (filter, handler) = e; + if filter.test(&value) { + Some(handler) + } else { + None + } + }); + + match handler { + Some(handler) => { + if let Err(err) = + handler.handle(value).await + { + self.error_policy + .handle_error(err) + .await; + } + } + None => { + log::warn!("Unhandled update: {:?}", value) + } } - }); + }}; + } - match handler { - Some(handler) => { - if let Err(err) = handler.handle(value).await { - self.error_policy.handle_error(err).await; - } - }, - None => log::warn!("Unhandled update: {:?}", value) + match kind { + UpdateKind::Message(mes) => { + call!(self.message_handlers, mes) } - }}; + UpdateKind::EditedMessage(mes) => { + call!(self.edited_message_handlers, mes) + } + UpdateKind::ChannelPost(post) => { + call!(self.channel_post_handlers, post) + } + UpdateKind::EditedChannelPost(post) => { + call!(self.edited_channel_post_handlers, post) + } + UpdateKind::InlineQuery(query) => { + call!(self.inline_query_handlers, query) + } + UpdateKind::ChosenInlineResult(result) => { + call!(self.chosen_inline_result_handlers, result) + } + UpdateKind::CallbackQuery(callback) => { + call!(self.callback_query_handlers, callback) + } + } } - - match kind { - UpdateKind::Message(mes) => call!(self.message_handlers, mes), - UpdateKind::EditedMessage(mes) => call!(self.edited_message_handlers, mes), - UpdateKind::ChannelPost(post) => call!(self.channel_post_handlers, post), - UpdateKind::EditedChannelPost(post) => call!(self.edited_channel_post_handlers, post), - UpdateKind::InlineQuery(query) => call!(self.inline_query_handlers, query), - UpdateKind::ChosenInlineResult(result) => call!(self.chosen_inline_result_handlers, result), - UpdateKind::CallbackQuery(callback) => call!(self.callback_query_handlers, callback), - } - } - }) + }) .await; } } -#[async_trait(?Send)] +#[async_trait(? Send)] impl<'a, U, E> crate::dispatcher::Dispatcher<'a, U> for Dispatcher<'a, E> where E: std::fmt::Debug, @@ -235,26 +269,35 @@ mod tests { use std::convert::Infallible; use std::sync::atomic::{AtomicI32, Ordering}; - use crate::{ - types::{ - Message, ChatKind, MessageKind, Sender, ForwardKind, MediaKind, Chat, User, Update, UpdateKind - }, - dispatcher::{simple::{Dispatcher, error_policy::ErrorPolicy}, updater::StreamUpdater}, - }; use futures::Stream; + use crate::{ + dispatcher::{ + simple::{error_policy::ErrorPolicy, Dispatcher}, + updater::StreamUpdater, + }, + types::{ + Chat, ChatKind, ForwardKind, MediaKind, Message, MessageKind, + Sender, Update, UpdateKind, User, + }, + }; + #[tokio::test] async fn first_handler_executes_1_time() { let counter = &AtomicI32::new(0); let counter2 = &AtomicI32::new(0); let mut dp = Dispatcher::<Infallible>::new(ErrorPolicy::Ignore) - .message_handler(true, |_mes: Message| async move { - counter.fetch_add(1, Ordering::SeqCst); + .message_handler(true, |_mes: Message| { + async move { + counter.fetch_add(1, Ordering::SeqCst); + } }) - .message_handler(true, |_mes: Message| async move { - counter2.fetch_add(1, Ordering::SeqCst); - Ok::<_, Infallible>(()) + .message_handler(true, |_mes: Message| { + async move { + counter2.fetch_add(1, Ordering::SeqCst); + Ok::<_, Infallible>(()) + } }); dp.dispatch(one_message_updater()).await; @@ -300,15 +343,17 @@ mod tests { } fn message_update() -> Update { - Update { id: 0, kind: UpdateKind::Message(message()) } + Update { + id: 0, + kind: UpdateKind::Message(message()), + } } - fn one_message_updater() -> StreamUpdater<impl Stream<Item=Result<Update, Infallible>>> { + fn one_message_updater( + ) -> StreamUpdater<impl Stream<Item = Result<Update, Infallible>>> { use futures::future::ready; use futures::stream; - StreamUpdater::new( - stream::once(ready(Ok(message_update()))) - ) + StreamUpdater::new(stream::once(ready(Ok(message_update())))) } } diff --git a/src/dispatcher/updater.rs b/src/dispatcher/updater.rs index 29df78d8..8de1025b 100644 --- a/src/dispatcher/updater.rs +++ b/src/dispatcher/updater.rs @@ -3,19 +3,18 @@ use std::{ task::{Context, Poll}, }; -use pin_project::pin_project; -use futures::{Stream, StreamExt, stream}; +use futures::{stream, Stream, StreamExt}; + +use pin_project::pin_project; -use crate::{ - types::Update, - RequestError, -}; use crate::bot::Bot; +use crate::{types::Update, RequestError}; // Currently just a placeholder, but I'll add here some methods /// Updater is stream of updates. /// -/// Telegram supports 2 ways of [getting updates]: [long polling](Long Polling) and webhook +/// Telegram supports 2 ways of [getting updates]: [long polling](Long Polling) +/// and webhook /// /// ## Long Polling /// @@ -99,14 +98,16 @@ use crate::bot::Bot; /// [GetUpdates]: crate::requests::GetUpdates /// [getting updates]: https://core.telegram.org/bots/api#getting-updates /// [wiki]: https://en.wikipedia.org/wiki/Push_technology#Long_polling -pub trait Updater: Stream<Item=Result<Update, <Self as Updater>::Error>> { +pub trait Updater: + Stream<Item = Result<Update, <Self as Updater>::Error>> +{ type Error; } #[pin_project] pub struct StreamUpdater<S> { #[pin] - stream: S + stream: S, } impl<S> StreamUpdater<S> { @@ -115,37 +116,49 @@ impl<S> StreamUpdater<S> { } } -impl<S, E> Stream for StreamUpdater<S> where S: Stream<Item=Result<Update, E>> { +impl<S, E> Stream for StreamUpdater<S> +where + S: Stream<Item = Result<Update, E>>, +{ type Item = Result<Update, E>; - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { + fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll<Option<Self::Item>> { self.project().stream.poll_next(cx) } } -impl<S, E> Updater for StreamUpdater<S> where S: Stream<Item=Result<Update, E>> { +impl<S, E> Updater for StreamUpdater<S> +where + S: Stream<Item = Result<Update, E>>, +{ type Error = E; } pub fn polling<'a>(bot: &'a Bot) -> impl Updater<Error = RequestError> + 'a { - let stream = stream::unfold((bot, 0), |(bot, mut offset)| async move { - // this match converts Result<Vec<_>, _> -> Vec<Result<_, _>> - let updates = match bot.get_updates().offset(offset).send().await { - Ok(updates) => { - if let Some(upd) = updates.last() { - offset = upd.id + 1; + let stream = stream::unfold((bot, 0), |(bot, mut offset)| { + async move { + // this match converts Result<Vec<_>, _> -> Vec<Result<_, _>> + let updates = match bot.get_updates().offset(offset).send().await { + Ok(updates) => { + if let Some(upd) = updates.last() { + offset = upd.id + 1; + } + updates.into_iter().map(|u| Ok(u)).collect::<Vec<_>>() } - updates.into_iter().map(|u| Ok(u)).collect::<Vec<_>>() - }, - Err(err) => vec![Err(err)] - }; - Some((stream::iter(updates), (bot, offset))) + Err(err) => vec![Err(err)], + }; + Some((stream::iter(updates), (bot, offset))) + } }) - .flatten(); + .flatten(); StreamUpdater { stream } } // TODO implement webhook (this actually require webserver and probably we // should add cargo feature that adds webhook) -//pub fn webhook<'a>(bot: &'a cfg: WebhookConfig) -> Updater<impl Stream<Item=Result<Update, ???>> + 'a> {} +//pub fn webhook<'a>(bot: &'a cfg: WebhookConfig) -> Updater<impl +// Stream<Item=Result<Update, ???>> + 'a> {} diff --git a/src/network/request.rs b/src/network/request.rs index 0222fad2..40bb8b2d 100644 --- a/src/network/request.rs +++ b/src/network/request.rs @@ -11,8 +11,8 @@ pub async fn request_multipart<T>( method_name: &str, params: Form, ) -> ResponseResult<T> - where - T: DeserializeOwned, +where + T: DeserializeOwned, { process_response( client @@ -30,8 +30,8 @@ pub async fn request_simple<T>( token: &str, method_name: &str, ) -> ResponseResult<T> - where - T: DeserializeOwned, +where + T: DeserializeOwned, { process_response( client diff --git a/src/requests/answer_pre_checkout_query.rs b/src/requests/answer_pre_checkout_query.rs index 289bad52..9087cab4 100644 --- a/src/requests/answer_pre_checkout_query.rs +++ b/src/requests/answer_pre_checkout_query.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, types::True, }; -use crate::bot::Bot; #[derive(Debug, Serialize, Clone)] /// Once the user has confirmed their payment and shipping details, the Bot API diff --git a/src/requests/answer_shipping_query.rs b/src/requests/answer_shipping_query.rs index 59d09cc9..4ba8fcd2 100644 --- a/src/requests/answer_shipping_query.rs +++ b/src/requests/answer_shipping_query.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ShippingOption, True}, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// If you sent an invoice requesting a shipping address and the parameter @@ -60,11 +60,7 @@ impl AnswerShippingQuery<'_> { } impl<'a> AnswerShippingQuery<'a> { - pub(crate) fn new<S, B>( - bot: &'a Bot, - shipping_query_id: S, - ok: B, - ) -> Self + pub(crate) fn new<S, B>(bot: &'a Bot, shipping_query_id: S, ok: B) -> Self where S: Into<String>, B: Into<bool>, diff --git a/src/requests/edit_message_live_location.rs b/src/requests/edit_message_live_location.rs index ddef8c11..b8d820b1 100644 --- a/src/requests/edit_message_live_location.rs +++ b/src/requests/edit_message_live_location.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to edit live location messages. A location can be edited @@ -64,11 +64,7 @@ impl EditMessageLiveLocation<'_> { } impl<'a> EditMessageLiveLocation<'a> { - pub(crate) fn new<Lt, Lg>( - bot: &'a Bot, - latitude: Lt, - longitude: Lg, - ) -> Self + pub(crate) fn new<Lt, Lg>(bot: &'a Bot, latitude: Lt, longitude: Lg) -> Self where Lt: Into<f64>, Lg: Into<f64>, diff --git a/src/requests/form_builder.rs b/src/requests/form_builder.rs index 7fdb6b55..b8896b8f 100644 --- a/src/requests/form_builder.rs +++ b/src/requests/form_builder.rs @@ -2,11 +2,11 @@ use std::path::PathBuf; use reqwest::multipart::Form; +use crate::types::InputFile; use crate::{ requests::utils, types::{ChatId, InputMedia, ParseMode}, }; -use crate::types::InputFile; /// This is a convenient struct that builds `reqwest::multipart::Form` /// from scratch. @@ -73,7 +73,10 @@ macro_rules! impl_for_struct { impl_for_struct!(bool, i32, i64); -impl<T> IntoFormValue for Option<T> where T: IntoFormValue { +impl<T> IntoFormValue for Option<T> +where + T: IntoFormValue, +{ fn into_form_value(self) -> Option<FormValue> { self.and_then(IntoFormValue::into_form_value) } @@ -81,8 +84,8 @@ impl<T> IntoFormValue for Option<T> where T: IntoFormValue { impl IntoFormValue for &[InputMedia] { fn into_form_value(self) -> Option<FormValue> { - let json = serde_json::to_string(self) - .expect("serde_json::to_string failed"); + let json = + serde_json::to_string(self).expect("serde_json::to_string failed"); Some(FormValue::Str(json)) } } diff --git a/src/requests/forward_message.rs b/src/requests/forward_message.rs index f0b05a99..5cce7880 100644 --- a/src/requests/forward_message.rs +++ b/src/requests/forward_message.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message}, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to forward messages of any kind. On success, the sent diff --git a/src/requests/get_chat.rs b/src/requests/get_chat.rs index b1d0c70d..0853de27 100644 --- a/src/requests/get_chat.rs +++ b/src/requests/get_chat.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{Chat, ChatId}, }; -use crate::bot::Bot; /// Use this method to get up to date information about the chat /// (current name of the user for one-on-one conversations, diff --git a/src/requests/get_file.rs b/src/requests/get_file.rs index 3c55e7a4..263705ac 100644 --- a/src/requests/get_file.rs +++ b/src/requests/get_file.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::File, }; -use crate::bot::Bot; /// Use this method to get basic info about a file and prepare it for /// downloading. For the moment, bots can download files of up to 20MB in size. diff --git a/src/requests/get_me.rs b/src/requests/get_me.rs index 5ec4eed3..4b1ad322 100644 --- a/src/requests/get_me.rs +++ b/src/requests/get_me.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::User, }; -use crate::bot::Bot; #[derive(Debug, Clone)] /// A simple method for testing your bot's auth token. Requires no parameters. @@ -25,7 +25,8 @@ impl Request for GetMe<'_> { impl GetMe<'_> { pub async fn send(self) -> ResponseResult<User> { - network::request_simple(self.bot.client(), self.bot.token(), "getMe").await + network::request_simple(self.bot.client(), self.bot.token(), "getMe") + .await } } diff --git a/src/requests/get_updates.rs b/src/requests/get_updates.rs index 50f1dac1..bc773bf3 100644 --- a/src/requests/get_updates.rs +++ b/src/requests/get_updates.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::Update, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] pub struct GetUpdates<'a> { diff --git a/src/requests/get_user_profile_photos.rs b/src/requests/get_user_profile_photos.rs index a66ff8ba..16c57eb2 100644 --- a/src/requests/get_user_profile_photos.rs +++ b/src/requests/get_user_profile_photos.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::UserProfilePhotos, }; -use crate::bot::Bot; ///Use this method to get a list of profile pictures for a user. Returns a /// UserProfilePhotos object. diff --git a/src/requests/kick_chat_member.rs b/src/requests/kick_chat_member.rs index 8861031b..c00690d3 100644 --- a/src/requests/kick_chat_member.rs +++ b/src/requests/kick_chat_member.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; -use crate::bot::Bot; /// Use this method to kick a user from a group, a supergroup or a channel. In /// the case of supergroups and channels, the user will not be able to return to @@ -50,11 +50,7 @@ impl KickChatMember<'_> { } impl<'a> KickChatMember<'a> { - pub(crate) fn new<C, U>( - bot: &'a Bot, - chat_id: C, - user_id: U, - ) -> Self + pub(crate) fn new<C, U>(bot: &'a Bot, chat_id: C, user_id: U) -> Self where C: Into<ChatId>, U: Into<i32>, diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 4940e317..ba2ddfc9 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -71,4 +71,4 @@ pub trait Request { /// Send this request. async fn send_boxed(self) -> ResponseResult<Self::Output>; -} \ No newline at end of file +} diff --git a/src/requests/pin_chat_message.rs b/src/requests/pin_chat_message.rs index c12e9e9e..d93f47bc 100644 --- a/src/requests/pin_chat_message.rs +++ b/src/requests/pin_chat_message.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; -use crate::bot::Bot; /// Use this method to get up to date information about the chat /// (current name of the user for one-on-one conversations, @@ -23,11 +23,7 @@ pub struct PinChatMessage<'a> { } impl<'a> PinChatMessage<'a> { - pub(crate) fn new<C, M>( - bot: &'a Bot, - chat_id: C, - message_id: M, - ) -> Self + pub(crate) fn new<C, M>(bot: &'a Bot, chat_id: C, message_id: M) -> Self where C: Into<ChatId>, M: Into<i32>, diff --git a/src/requests/promote_chat_member.rs b/src/requests/promote_chat_member.rs index 2a4ef01c..f37676fb 100644 --- a/src/requests/promote_chat_member.rs +++ b/src/requests/promote_chat_member.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; -use crate::bot::Bot; ///Use this method to promote or demote a user in a supergroup or a channel. /// The bot must be an administrator in the chat for this to work and must have @@ -73,11 +73,7 @@ impl PromoteChatMember<'_> { } impl<'a> PromoteChatMember<'a> { - pub(crate) fn new<C, U>( - bot: &'a Bot, - chat_id: C, - user_id: U, - ) -> Self + pub(crate) fn new<C, U>(bot: &'a Bot, chat_id: C, user_id: U) -> Self where C: Into<ChatId>, U: Into<i32>, diff --git a/src/requests/restrict_chat_member.rs b/src/requests/restrict_chat_member.rs index 6941c14c..51dead83 100644 --- a/src/requests/restrict_chat_member.rs +++ b/src/requests/restrict_chat_member.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, ChatPermissions, True}, }; -use crate::bot::Bot; /// Use this method to restrict a user in a supergroup. The bot must be an /// administrator in the supergroup for this to work and must have the diff --git a/src/requests/send_animation.rs b/src/requests/send_animation.rs index 89d70a58..a509e6dc 100644 --- a/src/requests/send_animation.rs +++ b/src/requests/send_animation.rs @@ -1,9 +1,9 @@ use async_trait::async_trait; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; use crate::bot::Bot; +use crate::network; +use crate::requests::{Request, ResponseResult}; +use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; ///TODO: add to bot api ///Use this method to send animation files (GIF or H.264/MPEG-4 AVC video @@ -87,11 +87,7 @@ impl SendAnimation<'_> { } impl<'a> SendAnimation<'a> { - pub(crate) fn new<C, S>( - bot: &'a Bot, - chat_id: C, - animation: S, - ) -> Self + pub(crate) fn new<C, S>(bot: &'a Bot, chat_id: C, animation: S) -> Self where C: Into<ChatId>, S: Into<String>, diff --git a/src/requests/send_audio.rs b/src/requests/send_audio.rs index 1eeb75e7..4b4411ef 100644 --- a/src/requests/send_audio.rs +++ b/src/requests/send_audio.rs @@ -1,13 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{ - form_builder::FormBuilder, Request, ResponseResult, - }, + requests::{form_builder::FormBuilder, Request, ResponseResult}, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, }; -use crate::bot::Bot; /// Use this method to send audio files, if you want Telegram clients to display /// them in the music player. Your audio must be in the .mp3 format. On success, @@ -87,7 +85,6 @@ impl SendAudio<'_> { .add("audio", self.audio) .add("thumb", self.thumb); - network::request_multipart( self.bot.client(), self.bot.token(), @@ -99,11 +96,7 @@ impl SendAudio<'_> { } impl<'a> SendAudio<'a> { - pub(crate) fn new<C, A>( - bot: &'a Bot, - chat_id: C, - audio: A, - ) -> Self + pub(crate) fn new<C, A>(bot: &'a Bot, chat_id: C, audio: A) -> Self where C: Into<ChatId>, A: Into<InputFile>, diff --git a/src/requests/send_chat_action.rs b/src/requests/send_chat_action.rs index 9ed0c511..403b88ba 100644 --- a/src/requests/send_chat_action.rs +++ b/src/requests/send_chat_action.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatAction, ChatId, True}, }; -use crate::bot::Bot; ///Use this method when you need to tell the user that something is happening /// on the bot's side. The status is set for 5 seconds or less (when a message @@ -48,7 +48,7 @@ impl SendChatAction<'_> { } impl<'a> SendChatAction<'a> { - pub(crate) fn new<Cid, Ca>(bot: &'a Bot, chat_id: Cid, action: Ca,) -> Self + pub(crate) fn new<Cid, Ca>(bot: &'a Bot, chat_id: Cid, action: Ca) -> Self where Cid: Into<ChatId>, Ca: Into<ChatAction>, diff --git a/src/requests/send_contact.rs b/src/requests/send_contact.rs index 50df7b68..f4465f48 100644 --- a/src/requests/send_contact.rs +++ b/src/requests/send_contact.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; -use crate::bot::Bot; /// Use this method to send phone contacts. /// returned. diff --git a/src/requests/send_document.rs b/src/requests/send_document.rs index d1b88526..93c5dc5b 100644 --- a/src/requests/send_document.rs +++ b/src/requests/send_document.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, }; -use crate::bot::Bot; // TODO: add method to bot/api @@ -80,11 +80,7 @@ impl SendDocument<'_> { } impl<'a> SendDocument<'a> { - pub(crate) fn new<C, D>( - bot: &'a Bot, - chat_id: C, - document: D, - ) -> Self + pub(crate) fn new<C, D>(bot: &'a Bot, chat_id: C, document: D) -> Self where C: Into<ChatId>, D: Into<String>, diff --git a/src/requests/send_location.rs b/src/requests/send_location.rs index 708d5441..5df4edf3 100644 --- a/src/requests/send_location.rs +++ b/src/requests/send_location.rs @@ -2,12 +2,12 @@ use serde::Serialize; use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to send point on the map. On success, the sent [`Message`] diff --git a/src/requests/send_media_group.rs b/src/requests/send_media_group.rs index c3e9ea8a..f9e0995a 100644 --- a/src/requests/send_media_group.rs +++ b/src/requests/send_media_group.rs @@ -1,13 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network::request_multipart, - requests::{ - form_builder::FormBuilder, Request, ResponseResult, - }, - types::{ChatId, InputMedia, Message, InputFile}, + requests::{form_builder::FormBuilder, Request, ResponseResult}, + types::{ChatId, InputFile, InputMedia, Message}, }; -use crate::bot::Bot; /// Use this method to send a group of photos or videos as an album. #[derive(Debug, Clone)] @@ -38,13 +36,16 @@ impl SendMediaGroup<'_> { .add("disable_notification", self.disable_notification) .add("reply_to_message_id", self.reply_to_message_id); - let form = self.media.into_iter().filter_map(|e| InputFile::from(e).into()) - .fold(form, |acc, path: std::path::PathBuf| - acc.add_file( - &path.file_name().unwrap().to_string_lossy().into_owned(), - path, - ) - ); + let form = self + .media + .into_iter() + .filter_map(|e| InputFile::from(e).into()) + .fold(form, |acc, path: std::path::PathBuf| { + acc.add_file( + &path.file_name().unwrap().to_string_lossy().into_owned(), + path, + ) + }); request_multipart( self.bot.client(), @@ -57,11 +58,7 @@ impl SendMediaGroup<'_> { } impl<'a> SendMediaGroup<'a> { - pub(crate) fn new<C, M>( - bot: &'a Bot, - chat_id: C, - media: M, - ) -> Self + pub(crate) fn new<C, M>(bot: &'a Bot, chat_id: C, media: M) -> Self where C: Into<ChatId>, M: Into<Vec<InputMedia>>, diff --git a/src/requests/send_message.rs b/src/requests/send_message.rs index 26c09ced..371b640d 100644 --- a/src/requests/send_message.rs +++ b/src/requests/send_message.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] /// Use this method to send text messages. On success, the sent [`Message`] is @@ -66,7 +66,7 @@ impl SendMessage<'_> { } impl<'a> SendMessage<'a> { - pub(crate) fn new<C, S>(bot: &'a Bot, chat_id: C, text: S,) -> Self + pub(crate) fn new<C, S>(bot: &'a Bot, chat_id: C, text: S) -> Self where C: Into<ChatId>, S: Into<String>, diff --git a/src/requests/send_photo.rs b/src/requests/send_photo.rs index 64f862b6..63a78666 100644 --- a/src/requests/send_photo.rs +++ b/src/requests/send_photo.rs @@ -1,13 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{ - form_builder::FormBuilder, Request, ResponseResult, - }, + requests::{form_builder::FormBuilder, Request, ResponseResult}, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, }; -use crate::bot::Bot; #[derive(Debug, Clone)] /// Use this method to send photos. On success, the sent [`Message`] is @@ -75,11 +73,7 @@ impl SendPhoto<'_> { } impl<'a> SendPhoto<'a> { - pub(crate) fn new<C, P>( - bot: &'a Bot, - chat_id: C, - photo: P, - ) -> Self + pub(crate) fn new<C, P>(bot: &'a Bot, chat_id: C, photo: P) -> Self where C: Into<ChatId>, P: Into<InputFile>, diff --git a/src/requests/send_poll.rs b/src/requests/send_poll.rs index f138ef7b..4322f6e6 100644 --- a/src/requests/send_poll.rs +++ b/src/requests/send_poll.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; -use crate::bot::Bot; /// Use this method to send a native poll. A native poll can't be sent to a /// private chat. On success, the sent Message is returned. diff --git a/src/requests/send_venue.rs b/src/requests/send_venue.rs index 59fa872e..02eebeca 100644 --- a/src/requests/send_venue.rs +++ b/src/requests/send_venue.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; -use crate::bot::Bot; /// Use this method to send information about a venue. /// Message is returned. diff --git a/src/requests/send_video.rs b/src/requests/send_video.rs index 9d08e67f..e6ab5712 100644 --- a/src/requests/send_video.rs +++ b/src/requests/send_video.rs @@ -1,9 +1,9 @@ use async_trait::async_trait; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; use crate::bot::Bot; +use crate::network; +use crate::requests::{Request, ResponseResult}; +use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; //TODO: add action to bot api ///Use this method to send video files, Telegram clients support mp4 videos @@ -89,11 +89,7 @@ impl SendVideo<'_> { } impl<'a> SendVideo<'a> { - pub(crate) fn new<C, V>( - bot: &'a Bot, - chat_id: C, - video: V, - ) -> Self + pub(crate) fn new<C, V>(bot: &'a Bot, chat_id: C, video: V) -> Self where C: Into<ChatId>, V: Into<String>, diff --git a/src/requests/send_video_note.rs b/src/requests/send_video_note.rs index 89e304e7..bd3eb316 100644 --- a/src/requests/send_video_note.rs +++ b/src/requests/send_video_note.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, }; -use crate::bot::Bot; ///As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 /// minute long. Use this method to send video messages. On success, the sent @@ -76,11 +76,7 @@ impl SendVideoNote<'_> { } impl<'a> SendVideoNote<'a> { - pub(crate) fn new<C, V>( - bot: &'a Bot, - chat_id: C, - video_note: V, - ) -> Self + pub(crate) fn new<C, V>(bot: &'a Bot, chat_id: C, video_note: V) -> Self where C: Into<ChatId>, V: Into<String>, diff --git a/src/requests/send_voice.rs b/src/requests/send_voice.rs index d594fd7a..b591defc 100644 --- a/src/requests/send_voice.rs +++ b/src/requests/send_voice.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, }; -use crate::bot::Bot; ///Use this method to send audio files, if you want Telegram clients to display /// the file as a playable voice message. For this to work, your audio must be @@ -73,11 +73,7 @@ impl SendVoice<'_> { } impl<'a> SendVoice<'a> { - pub(crate) fn new<C, V>( - bot: &'a Bot, - chat_id: C, - voice: V, - ) -> Self + pub(crate) fn new<C, V>(bot: &'a Bot, chat_id: C, voice: V) -> Self where C: Into<ChatId>, V: Into<String>, diff --git a/src/requests/stop_message_live_location.rs b/src/requests/stop_message_live_location.rs index 976cd6fc..541690c2 100644 --- a/src/requests/stop_message_live_location.rs +++ b/src/requests/stop_message_live_location.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, InlineKeyboardMarkup, Message}, }; -use crate::bot::Bot; /// Use this method to stop updating a live location message before live_period /// expires. On success, if the message was sent by the bot, the sent Message is diff --git a/src/requests/unban_chat_member.rs b/src/requests/unban_chat_member.rs index b015e800..9a2f266c 100644 --- a/src/requests/unban_chat_member.rs +++ b/src/requests/unban_chat_member.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::ChatId, }; -use crate::bot::Bot; /// Use this method to unban a previously kicked user in a supergroup or /// channel. The user will not return to the group or channel automatically, but @@ -44,11 +44,7 @@ impl UnbanChatMember<'_> { } impl<'a> UnbanChatMember<'a> { - pub(crate) fn new<C, U>( - bot: &'a Bot, - chat_id: C, - user_id: U, - ) -> Self + pub(crate) fn new<C, U>(bot: &'a Bot, chat_id: C, user_id: U) -> Self where C: Into<ChatId>, U: Into<i32>, diff --git a/src/requests/unpin_chat_message.rs b/src/requests/unpin_chat_message.rs index ac98e34a..0571f671 100644 --- a/src/requests/unpin_chat_message.rs +++ b/src/requests/unpin_chat_message.rs @@ -1,11 +1,11 @@ use async_trait::async_trait; +use crate::bot::Bot; use crate::{ network, - requests::{Request, ResponseResult}, + requests::{Request, ResponseResult}, types::{ChatId, True}, }; -use crate::bot::Bot; #[derive(Debug, Clone, Serialize)] pub struct UnpinChatMessage<'a> { diff --git a/src/types/inline_keyboard_markup.rs b/src/types/inline_keyboard_markup.rs index e52fccda..2ca92ee4 100644 --- a/src/types/inline_keyboard_markup.rs +++ b/src/types/inline_keyboard_markup.rs @@ -16,9 +16,7 @@ pub struct InlineKeyboardMarkup { /// /// Example: /// ``` -/// use telebofr::types::{ -/// InlineKeyboardButton, InlineKeyboardMarkup, -/// }; +/// use telebofr::types::{InlineKeyboardButton, InlineKeyboardMarkup}; /// /// let url_button = InlineKeyboardButton::url( /// "text".to_string(), diff --git a/src/types/message.rs b/src/types/message.rs index c658dd42..188d3bdb 100644 --- a/src/types/message.rs +++ b/src/types/message.rs @@ -1,4 +1,8 @@ -use crate::types::{Animation, Audio, Chat, Contact, Document, Game, InlineKeyboardMarkup, Invoice, Location, MessageEntity, PassportData, PhotoSize, Poll, Sticker, SuccessfulPayment, User, Venue, Video, VideoNote, Voice, True}; +use crate::types::{ + Animation, Audio, Chat, Contact, Document, Game, InlineKeyboardMarkup, + Invoice, Location, MessageEntity, PassportData, PhotoSize, Poll, Sticker, + SuccessfulPayment, True, User, Venue, Video, VideoNote, Voice, +}; #[derive(Debug, Deserialize, PartialEq, Clone)] pub struct Message { @@ -10,7 +14,6 @@ pub struct Message { pub kind: MessageKind, } - #[derive(Debug, Deserialize, PartialEq, Clone)] #[serde(untagged)] pub enum MessageKind { @@ -187,24 +190,25 @@ pub enum MediaKind { mod getters { use std::ops::Deref; + use crate::types::message::MessageKind::{Pinned, SupergroupChatCreated}; use crate::types::{ - self, Message, Sender, User, ForwardedFrom, Chat, MessageEntity, - PhotoSize, True, + self, message::{ - MessageKind::{ - Common, NewChatMembers, LeftChatMember, NewChatTitle, - NewChatPhoto, DeleteChatPhoto, GroupChatCreated, - ChannelChatCreated, Migrate, Invoice, SuccessfulPayment, - ConnectedWebsite, PassportData - }, + ForwardKind::{ChannelForward, NonChannelForward, Origin}, MediaKind::{ - Text, Video, Photo, Animation, Audio, Document, Voice, Game, - Sticker, VideoNote, Contact, Location, Poll, Venue + Animation, Audio, Contact, Document, Game, Location, Photo, + Poll, Sticker, Text, Venue, Video, VideoNote, Voice, + }, + MessageKind::{ + ChannelChatCreated, Common, ConnectedWebsite, DeleteChatPhoto, + GroupChatCreated, Invoice, LeftChatMember, Migrate, + NewChatMembers, NewChatPhoto, NewChatTitle, PassportData, + SuccessfulPayment, }, - ForwardKind::{NonChannelForward, ChannelForward, Origin} }, + Chat, ForwardedFrom, Message, MessageEntity, PhotoSize, Sender, True, + User, }; - use crate::types::message::MessageKind::{SupergroupChatCreated, Pinned}; /// Getters for [Message] fields from [telegram docs]. /// @@ -223,49 +227,67 @@ mod getters { /// `forward_sender_name` pub fn forward_from(&self) -> Option<&ForwardedFrom> { match &self.kind { - Common { forward_kind: NonChannelForward { from, .. }, .. } => - Some(from), + Common { + forward_kind: NonChannelForward { from, .. }, + .. + } => Some(from), _ => None, } } pub fn forward_from_chat(&self) -> Option<&Chat> { match &self.kind { - Common { forward_kind: ChannelForward { chat, .. }, .. } => - Some(chat), + Common { + forward_kind: ChannelForward { chat, .. }, + .. + } => Some(chat), _ => None, } } pub fn forward_from_message_id(&self) -> Option<&i32> { match &self.kind { - Common { forward_kind: ChannelForward { message_id, .. }, .. } => - Some(message_id), + Common { + forward_kind: ChannelForward { message_id, .. }, + .. + } => Some(message_id), _ => None, } } pub fn forward_signature(&self) -> Option<&str> { match &self.kind { - Common { forward_kind: ChannelForward { signature, .. }, .. } => - signature.as_ref().map(Deref::deref), + Common { + forward_kind: ChannelForward { signature, .. }, + .. + } => signature.as_ref().map(Deref::deref), _ => None, } } pub fn forward_date(&self) -> Option<&i32> { match &self.kind { - Common { forward_kind: ChannelForward { date, .. }, .. } | - Common { forward_kind: NonChannelForward { date, .. }, .. } => - Some(date), + Common { + forward_kind: ChannelForward { date, .. }, + .. + } + | Common { + forward_kind: NonChannelForward { date, .. }, + .. + } => Some(date), _ => None, } } pub fn reply_to_message(&self) -> Option<&Message> { match &self.kind { - Common { forward_kind: Origin { reply_to_message, .. }, .. } => - reply_to_message.as_ref().map(Deref::deref), + Common { + forward_kind: + Origin { + reply_to_message, .. + }, + .. + } => reply_to_message.as_ref().map(Deref::deref), _ => None, } } @@ -279,104 +301,172 @@ mod getters { pub fn media_group_id(&self) -> Option<&str> { match &self.kind { - Common { media_kind: Video { media_group_id, .. }, .. } | - Common { media_kind: Photo { media_group_id, .. }, .. } => - media_group_id.as_ref().map(Deref::deref), + Common { + media_kind: Video { media_group_id, .. }, + .. + } + | Common { + media_kind: Photo { media_group_id, .. }, + .. + } => media_group_id.as_ref().map(Deref::deref), _ => None, } } pub fn text(&self) -> Option<&str> { match &self.kind { - Common { media_kind: Text { text, .. }, .. } => Some(text), + Common { + media_kind: Text { text, .. }, + .. + } => Some(text), _ => None, } } pub fn entities(&self) -> Option<&[MessageEntity]> { match &self.kind { - Common { media_kind: Text { entities, .. }, .. } => - Some(entities), + Common { + media_kind: Text { entities, .. }, + .. + } => Some(entities), _ => None, } } pub fn caption_entities(&self) -> Option<&[MessageEntity]> { match &self.kind { - Common { media_kind: Animation { caption_entities, .. }, .. } | - Common { media_kind: Audio { caption_entities, .. }, .. } | - Common { media_kind: Document { caption_entities, .. }, .. } | - Common { media_kind: Photo { caption_entities, .. }, .. } | - Common { media_kind: Video { caption_entities, .. }, .. } | - Common { media_kind: Voice { caption_entities, .. }, .. } => - Some(caption_entities), + Common { + media_kind: + Animation { + caption_entities, .. + }, + .. + } + | Common { + media_kind: + Audio { + caption_entities, .. + }, + .. + } + | Common { + media_kind: + Document { + caption_entities, .. + }, + .. + } + | Common { + media_kind: + Photo { + caption_entities, .. + }, + .. + } + | Common { + media_kind: + Video { + caption_entities, .. + }, + .. + } + | Common { + media_kind: + Voice { + caption_entities, .. + }, + .. + } => Some(caption_entities), _ => None, } } pub fn audio(&self) -> Option<&types::Audio> { match &self.kind { - Common { media_kind: Audio { audio, .. }, .. } => Some(audio), + Common { + media_kind: Audio { audio, .. }, + .. + } => Some(audio), _ => None, } } pub fn document(&self) -> Option<&types::Document> { match &self.kind { - Common { media_kind: Document { document, .. }, .. } => - Some(document), + Common { + media_kind: Document { document, .. }, + .. + } => Some(document), _ => None, } } pub fn animation(&self) -> Option<&types::Animation> { match &self.kind { - Common { media_kind: Animation { animation, .. }, .. } => - Some(animation), + Common { + media_kind: Animation { animation, .. }, + .. + } => Some(animation), _ => None, } } pub fn game(&self) -> Option<&types::Game> { match &self.kind { - Common { media_kind: Game { game, .. }, .. } => Some(game), + Common { + media_kind: Game { game, .. }, + .. + } => Some(game), _ => None, } } pub fn photo(&self) -> Option<&[PhotoSize]> { match &self.kind { - Common { media_kind: Photo { photo, .. }, .. } => Some(photo), + Common { + media_kind: Photo { photo, .. }, + .. + } => Some(photo), _ => None, } } pub fn sticker(&self) -> Option<&types::Sticker> { match &self.kind { - Common { media_kind: Sticker { sticker, .. }, .. } => - Some(sticker), + Common { + media_kind: Sticker { sticker, .. }, + .. + } => Some(sticker), _ => None, } } pub fn video(&self) -> Option<&types::Video> { match &self.kind { - Common { media_kind: Video { video, .. }, .. } => Some(video), + Common { + media_kind: Video { video, .. }, + .. + } => Some(video), _ => None, } } pub fn voice(&self) -> Option<&types::Voice> { match &self.kind { - Common { media_kind: Voice { voice, .. }, .. } => Some(voice), + Common { + media_kind: Voice { voice, .. }, + .. + } => Some(voice), _ => None, } } pub fn video_note(&self) -> Option<&types::VideoNote> { match &self.kind { - Common { media_kind: VideoNote { video_note, .. }, .. } => - Some(video_note), + Common { + media_kind: VideoNote { video_note, .. }, + .. + } => Some(video_note), _ => None, } } @@ -384,12 +474,14 @@ mod getters { pub fn caption(&self) -> Option<&str> { match &self.kind { Common { media_kind, .. } => match media_kind { - Animation { caption, ..} | - Audio { caption, ..} | - Document { caption, ..} | - Photo { caption, ..} | - Video { caption, ..} | - Voice { caption, ..} => caption.as_ref().map(Deref::deref), + Animation { caption, .. } + | Audio { caption, .. } + | Document { caption, .. } + | Photo { caption, .. } + | Video { caption, .. } + | Voice { caption, .. } => { + caption.as_ref().map(Deref::deref) + } _ => None, }, _ => None, @@ -398,29 +490,40 @@ mod getters { pub fn contact(&self) -> Option<&types::Contact> { match &self.kind { - Common { media_kind: Contact { contact }, .. } => Some(contact), + Common { + media_kind: Contact { contact }, + .. + } => Some(contact), _ => None, } } pub fn location(&self) -> Option<&types::Location> { match &self.kind { - Common { media_kind: Location { location, .. }, .. } => - Some(location), + Common { + media_kind: Location { location, .. }, + .. + } => Some(location), _ => None, } } pub fn venue(&self) -> Option<&types::Venue> { match &self.kind { - Common { media_kind: Venue { venue, .. }, .. } => Some(venue), + Common { + media_kind: Venue { venue, .. }, + .. + } => Some(venue), _ => None, } } pub fn poll(&self) -> Option<&types::Poll> { match &self.kind { - Common { media_kind: Poll { poll, .. }, .. } => Some(poll), + Common { + media_kind: Poll { poll, .. }, + .. + } => Some(poll), _ => None, } } @@ -457,47 +560,55 @@ mod getters { // mb smt like `is_delete_chat_photo(&self) -> bool`? pub fn delete_chat_photo(&self) -> Option<True> { match &self.kind { - DeleteChatPhoto { delete_chat_photo } => - Some(*delete_chat_photo), + DeleteChatPhoto { delete_chat_photo } => { + Some(*delete_chat_photo) + } _ => None, } } pub fn group_chat_created(&self) -> Option<True> { match &self.kind { - GroupChatCreated { group_chat_created } => - Some(*group_chat_created), + GroupChatCreated { group_chat_created } => { + Some(*group_chat_created) + } _ => None, } } pub fn super_group_chat_created(&self) -> Option<True> { match &self.kind { - SupergroupChatCreated { supergroup_chat_created } => - Some(*supergroup_chat_created), + SupergroupChatCreated { + supergroup_chat_created, + } => Some(*supergroup_chat_created), _ => None, } } pub fn channel_chat_created(&self) -> Option<True> { match &self.kind { - ChannelChatCreated { channel_chat_created } => - Some(*channel_chat_created), + ChannelChatCreated { + channel_chat_created, + } => Some(*channel_chat_created), _ => None, } } pub fn migrate_to_chat_id(&self) -> Option<&i64> { match &self.kind { - Migrate { migrate_to_chat_id, .. } => Some(migrate_to_chat_id), + Migrate { + migrate_to_chat_id, .. + } => Some(migrate_to_chat_id), _ => None, } } pub fn migrate_from_chat_id(&self) -> Option<&i64> { match &self.kind { - Migrate { migrate_from_chat_id, .. } => - Some(migrate_from_chat_id), + Migrate { + migrate_from_chat_id, + .. + } => Some(migrate_from_chat_id), _ => None, } } @@ -516,25 +627,24 @@ mod getters { } } - pub fn successful_payment(&self) -> Option<&types::SuccessfulPayment> { match &self.kind { - SuccessfulPayment { successful_payment } => - Some(successful_payment), + SuccessfulPayment { successful_payment } => { + Some(successful_payment) + } _ => None, } } - pub fn connected_website(&self) -> Option<&str> { match &self.kind { - ConnectedWebsite { connected_website } => - Some(connected_website), + ConnectedWebsite { connected_website } => { + Some(connected_website) + } _ => None, } } - pub fn passport_data(&self) -> Option<&types::PassportData> { match &self.kind { PassportData { passport_data } => Some(passport_data), @@ -542,7 +652,6 @@ mod getters { } } - pub fn reply_markup(&self) -> Option<&types::InlineKeyboardMarkup> { match &self.kind { Common { reply_markup, .. } => reply_markup.as_ref(), @@ -552,7 +661,6 @@ mod getters { } } - #[cfg(test)] mod tests { use serde_json::from_str; From eee360792a999c0683c63d9ffabe29eba5acc4b8 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 10:41:18 +0600 Subject: [PATCH 11/66] Fix the errors --- src/bot/download.rs | 3 ++- src/dispatcher/simple/mod.rs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/bot/download.rs b/src/bot/download.rs index 4488e3b5..331de593 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -17,9 +17,10 @@ impl Bot { /// ## Examples /// /// ```no_run - /// use telebofr::{bot::requests::Request, types::File as TgFile}; + /// use telebofr::types::File as TgFile; /// use tokio::fs::File; /// # use telebofr::RequestError; + /// use telebofr::bot::Bot; /// /// # async fn run() -> Result<(), Box<dyn std::error::Error>> { /// let bot = Bot::new("TOKEN"); diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 99c66e28..23fa47ab 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -32,10 +32,11 @@ type Handlers<'a, T, E> = /// /// Simplest example: /// ```no_run -/// # async fn run() { +/// # use telebofr::bot::Bot; +/// use telebofr::types::Message; +/// async fn run() { /// use std::convert::Infallible; /// use telebofr::{ -/// bot::types::Message, /// dispatcher::{ /// simple::{error_policy::ErrorPolicy, Dispatcher}, /// updater::polling, From 2fe88cbfe3a19d74d27648b26ffbbd14a3469c60 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 10:46:42 +0600 Subject: [PATCH 12/66] Fix some Clippy's lints --- src/dispatcher/updater.rs | 2 +- src/requests/form_builder.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dispatcher/updater.rs b/src/dispatcher/updater.rs index 8de1025b..7b0017fb 100644 --- a/src/dispatcher/updater.rs +++ b/src/dispatcher/updater.rs @@ -146,7 +146,7 @@ pub fn polling<'a>(bot: &'a Bot) -> impl Updater<Error = RequestError> + 'a { if let Some(upd) = updates.last() { offset = upd.id + 1; } - updates.into_iter().map(|u| Ok(u)).collect::<Vec<_>>() + updates.into_iter().map(Ok).collect::<Vec<_>>() } Err(err) => vec![Err(err)], }; diff --git a/src/requests/form_builder.rs b/src/requests/form_builder.rs index b8896b8f..01698d5c 100644 --- a/src/requests/form_builder.rs +++ b/src/requests/form_builder.rs @@ -110,7 +110,7 @@ impl IntoFormValue for ChatId { fn into_form_value(self) -> Option<FormValue> { let string = match self { ChatId::Id(id) => id.to_string(), - ChatId::ChannelUsername(username) => username.clone(), + ChatId::ChannelUsername(username) => username, }; Some(FormValue::Str(string)) } @@ -118,7 +118,7 @@ impl IntoFormValue for ChatId { impl IntoFormValue for String { fn into_form_value(self) -> Option<FormValue> { - Some(FormValue::Str(self.to_owned())) + Some(FormValue::Str(self)) } } From d0f885253393edd18862190dd99246b08dabc3fa Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 13:25:53 +0600 Subject: [PATCH 13/66] Fix a typo --- src/requests/unpin_chat_message.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requests/unpin_chat_message.rs b/src/requests/unpin_chat_message.rs index 0571f671..aabf57dc 100644 --- a/src/requests/unpin_chat_message.rs +++ b/src/requests/unpin_chat_message.rs @@ -10,7 +10,7 @@ use crate::{ #[derive(Debug, Clone, Serialize)] pub struct UnpinChatMessage<'a> { #[serde(skip_serializing)] - pub bot: &'a Bot, + bot: &'a Bot, pub chat_id: ChatId, } From a3825d612d623d46ce499c29f40c22eac5aacb1f Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 13:33:26 +0600 Subject: [PATCH 14/66] Provide &self instead of &&self (bot/api.h) --- src/bot/api.rs | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index 01b4d8ff..ea3be1bc 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -14,11 +14,11 @@ use crate::{ /// Telegram functions impl Bot { pub fn get_me(&self) -> GetMe { - GetMe::new(&self) + GetMe::new(self) } pub fn get_updates(&self) -> GetUpdates { - GetUpdates::new(&self) + GetUpdates::new(self) } pub fn send_message<C, T>(&self, chat_id: C, text: T) -> SendMessage @@ -26,7 +26,7 @@ impl Bot { C: Into<ChatId>, T: Into<String>, { - SendMessage::new(&self, chat_id, text) + SendMessage::new(self, chat_id, text) } pub fn edit_message_live_location<Lt, Lg>( @@ -38,7 +38,7 @@ impl Bot { Lt: Into<f64>, Lg: Into<f64>, { - EditMessageLiveLocation::new(&self, latitude, longitude) + EditMessageLiveLocation::new(self, latitude, longitude) } pub fn forward_message<C, F, M>( @@ -52,7 +52,7 @@ impl Bot { F: Into<ChatId>, M: Into<i32>, { - ForwardMessage::new(&self, chat_id, from_chat_id, message_id) + ForwardMessage::new(self, chat_id, from_chat_id, message_id) } pub fn send_audio<C, A>(&self, chat_id: C, audio: A) -> SendAudio @@ -60,7 +60,7 @@ impl Bot { C: Into<ChatId>, A: Into<InputFile>, { - SendAudio::new(&self, chat_id, audio) + SendAudio::new(self, chat_id, audio) } pub fn send_location<C, Lt, Lg>( @@ -74,7 +74,7 @@ impl Bot { Lt: Into<f64>, Lg: Into<f64>, { - SendLocation::new(&self, chat_id, latitude, longitude) + SendLocation::new(self, chat_id, latitude, longitude) } pub fn send_media_group<C, M>(&self, chat_id: C, media: M) -> SendMediaGroup @@ -82,7 +82,7 @@ impl Bot { C: Into<ChatId>, M: Into<Vec<InputMedia>>, { - SendMediaGroup::new(&self, chat_id, media) + SendMediaGroup::new(self, chat_id, media) } pub fn send_photo<C, P>(&self, chat_id: C, photo: P) -> SendPhoto @@ -90,18 +90,18 @@ impl Bot { C: Into<ChatId>, P: Into<InputFile>, { - SendPhoto::new(&self, chat_id, photo) + SendPhoto::new(self, chat_id, photo) } pub fn stop_message_live_location(&self) -> StopMessageLiveLocation { - StopMessageLiveLocation::new(&self) + StopMessageLiveLocation::new(self) } pub fn get_file<F>(&self, file_id: F) -> GetFile where F: Into<String>, { - GetFile::new(&self, file_id) + GetFile::new(self, file_id) } pub fn answer_pre_checkout_query<I, O>( @@ -113,7 +113,7 @@ impl Bot { I: Into<String>, O: Into<bool>, { - AnswerPreCheckoutQuery::new(&self, pre_checkout_query_id, ok) + AnswerPreCheckoutQuery::new(self, pre_checkout_query_id, ok) } pub fn answer_shipping_query<I, O>( @@ -125,7 +125,7 @@ impl Bot { I: Into<String>, O: Into<bool>, { - AnswerShippingQuery::new(&self, shipping_query_id, ok) + AnswerShippingQuery::new(self, shipping_query_id, ok) } pub fn kick_chat_member<C, U>( @@ -137,7 +137,7 @@ impl Bot { C: Into<ChatId>, U: Into<i32>, { - KickChatMember::new(&self, chat_id, user_id) + KickChatMember::new(self, chat_id, user_id) } pub fn pin_chat_message<C, M>( @@ -149,7 +149,7 @@ impl Bot { C: Into<ChatId>, M: Into<i32>, { - PinChatMessage::new(&self, chat_id, message_id) + PinChatMessage::new(self, chat_id, message_id) } pub fn promote_chat_member<C, U>( @@ -161,7 +161,7 @@ impl Bot { C: Into<ChatId>, U: Into<i32>, { - PromoteChatMember::new(&self, chat_id, user_id) + PromoteChatMember::new(self, chat_id, user_id) } pub fn restrict_chat_member<C, U, P>( @@ -175,7 +175,7 @@ impl Bot { U: Into<i32>, P: Into<ChatPermissions>, { - RestrictChatMember::new(&self, chat_id, user_id, permissions) + RestrictChatMember::new(self, chat_id, user_id, permissions) } pub fn send_chat_action<C, A>( @@ -187,7 +187,7 @@ impl Bot { C: Into<ChatId>, A: Into<ChatAction>, { - SendChatAction::new(&self, chat_id, action) + SendChatAction::new(self, chat_id, action) } pub fn send_contact<C, P, F>( @@ -201,7 +201,7 @@ impl Bot { P: Into<String>, F: Into<String>, { - SendContact::new(&self, chat_id, phone_number, first_name) + SendContact::new(self, chat_id, phone_number, first_name) } pub fn send_poll<C, Q, O>( @@ -215,7 +215,7 @@ impl Bot { Q: Into<String>, O: Into<Vec<String>>, { - SendPoll::new(&self, chat_id, question, options) + SendPoll::new(self, chat_id, question, options) } pub fn send_venue<C, Lt, Lg, T, A>( @@ -233,7 +233,7 @@ impl Bot { T: Into<String>, A: Into<String>, { - SendVenue::new(&self, chat_id, latitude, longitude, title, address) + SendVenue::new(self, chat_id, latitude, longitude, title, address) } pub fn send_video_note<C, V>( @@ -245,7 +245,7 @@ impl Bot { C: Into<ChatId>, V: Into<String>, // TODO: InputFile { - SendVideoNote::new(&self, chat_id, video_note) + SendVideoNote::new(self, chat_id, video_note) } pub fn send_voice<C, V>(&self, chat_id: C, voice: V) -> SendVoice @@ -253,7 +253,7 @@ impl Bot { C: Into<ChatId>, V: Into<String>, // TODO: InputFile { - SendVoice::new(&self, chat_id, voice) + SendVoice::new(self, chat_id, voice) } pub fn unban_chat_member<C, U>( @@ -265,13 +265,13 @@ impl Bot { C: Into<ChatId>, U: Into<i32>, { - UnbanChatMember::new(&self, chat_id, user_id) + UnbanChatMember::new(self, chat_id, user_id) } pub fn unpin_chat_message<C>(&self, chat_id: C) -> UnpinChatMessage where C: Into<ChatId>, { - UnpinChatMessage::new(&self, chat_id) + UnpinChatMessage::new(self, chat_id) } } From 07ad96556254c6f583e1d21bdf48ce4b8853da87 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 14:02:36 +0600 Subject: [PATCH 15/66] Prettify src/requests.rs and src/types.rs --- src/requests/mod.rs | 56 ++++++++------- src/types/mod.rs | 170 +++++++++++++++++++++----------------------- 2 files changed, 115 insertions(+), 111 deletions(-) diff --git a/src/requests/mod.rs b/src/requests/mod.rs index ba2ddfc9..a1ecef59 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -1,30 +1,38 @@ //! Raw API functions. +use async_trait::async_trait; use serde::de::DeserializeOwned; -use async_trait::async_trait; - -use crate::RequestError; - -pub use self::{ - answer_pre_checkout_query::AnswerPreCheckoutQuery, - answer_shipping_query::AnswerShippingQuery, - edit_message_live_location::EditMessageLiveLocation, - forward_message::ForwardMessage, get_chat::GetChat, get_file::GetFile, - get_me::GetMe, get_updates::GetUpdates, - get_user_profile_photos::GetUserProfilePhotos, - kick_chat_member::KickChatMember, pin_chat_message::PinChatMessage, - promote_chat_member::PromoteChatMember, - restrict_chat_member::RestrictChatMember, send_animation::SendAnimation, - send_audio::SendAudio, send_chat_action::SendChatAction, - send_contact::SendContact, send_document::SendDocument, - send_location::SendLocation, send_media_group::SendMediaGroup, - send_message::SendMessage, send_photo::SendPhoto, send_poll::SendPoll, - send_venue::SendVenue, send_video::SendVideo, - send_video_note::SendVideoNote, send_voice::SendVoice, - stop_message_live_location::StopMessageLiveLocation, - unban_chat_member::UnbanChatMember, unpin_chat_message::UnpinChatMessage, -}; +pub use answer_pre_checkout_query::*; +pub use answer_shipping_query::*; +pub use edit_message_live_location::*; +pub use forward_message::*; +pub use get_chat::*; +pub use get_file::*; +pub use get_me::*; +pub use get_updates::*; +pub use get_user_profile_photos::*; +pub use kick_chat_member::*; +pub use pin_chat_message::*; +pub use promote_chat_member::*; +pub use restrict_chat_member::*; +pub use send_animation::*; +pub use send_audio::*; +pub use send_chat_action::*; +pub use send_contact::*; +pub use send_document::*; +pub use send_location::*; +pub use send_media_group::*; +pub use send_message::*; +pub use send_photo::*; +pub use send_poll::*; +pub use send_venue::*; +pub use send_video::*; +pub use send_video_note::*; +pub use send_voice::*; +pub use stop_message_live_location::*; +pub use unban_chat_member::*; +pub use unpin_chat_message::*; mod form_builder; mod utils; @@ -61,7 +69,7 @@ mod unban_chat_member; mod unpin_chat_message; /// A type that is returned from `Request::send_boxed`. -pub type ResponseResult<T> = Result<T, RequestError>; +pub type ResponseResult<T> = Result<T, crate::RequestError>; /// A request that can be sent to Telegram. #[async_trait] diff --git a/src/types/mod.rs b/src/types/mod.rs index b3268627..ae62090e 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,92 +1,88 @@ //! Raw API structures. -pub use self::{ - animation::Animation, - audio::Audio, - callback_game::CallbackGame, - callback_query::CallbackQuery, - chat::{Chat, ChatKind, NonPrivateChatKind}, - chat_action::ChatAction, - chat_id::ChatId, - chat_member::{ChatMember, ChatMemberStatus}, - chat_permissions::ChatPermissions, - chat_photo::ChatPhoto, - chosen_inline_result::ChosenInlineResult, - contact::Contact, - document::Document, - encrypted_credintials::EncryptedCredentials, - encrypted_passport_element::{ - EncryptedPassportElement, EncryptedPassportElementKind, - }, - file::File, - force_reply::ForceReply, - game::Game, - game_high_score::GameHighScore, - inline_keyboard_button::{InlineKeyboardButton, InlineKeyboardButtonKind}, - inline_keyboard_markup::InlineKeyboardMarkup, - inline_query::InlineQuery, - inline_query_result::InlineQueryResult, - inline_query_result_article::InlineQueryResultArticle, - inline_query_result_audio::InlineQueryResultAudio, - inline_query_result_cached_audio::InlineQueryResultCachedAudio, - inline_query_result_cached_document::InlineQueryResultCachedDocument, - inline_query_result_cached_gif::InlineQueryResultCachedGif, - inline_query_result_cached_mpeg4_gif::InlineQueryResultCachedMpeg4Gif, - inline_query_result_cached_photo::InlineQueryResultCachedPhoto, - inline_query_result_cached_sticker::InlineQueryResultCachedSticker, - inline_query_result_cached_video::InlineQueryResultCachedVideo, - inline_query_result_cached_voice::InlineQueryResultCachedVoice, - inline_query_result_contact::InlineQueryResultContact, - inline_query_result_document::InlineQueryResultDocument, - inline_query_result_game::InlineQueryResultGame, - inline_query_result_gif::InlineQueryResultGif, - inline_query_result_location::InlineQueryResultLocation, - inline_query_result_mpeg4_gif::InlineQueryResultMpeg4Gif, - inline_query_result_photo::InlineQueryResultPhoto, - inline_query_result_venue::InlineQueryResultVenue, - inline_query_result_video::InlineQueryResultVideo, - inline_query_result_voice::InlineQueryResultVoice, - input_file::InputFile, - input_media::InputMedia, - input_message_content::InputMessageContent, - invoice::Invoice, - keyboard_button::KeyboardButton, - label_price::LabeledPrice, - location::Location, - login_url::LoginUrl, - mask_position::MaskPosition, - message::{ - ForwardKind, ForwardedFrom, MediaKind, Message, MessageKind, Sender, - }, - message_entity::MessageEntity, - order_info::OrderInfo, - parse_mode::ParseMode, - passport_data::PassportData, - passport_file::PassportFile, - photo_size::PhotoSize, - poll::{Poll, PollOption}, - pre_checkout_query::PreCheckoutQuery, - reply_keyboard_markup::ReplyKeyboardMarkup, - reply_keyboard_remove::ReplyKeyboardRemove, - reply_markup::ReplyMarkup, - response_parameters::ResponseParameters, - send_invoice::SendInvoice, - shipping_address::ShippingAddress, - shipping_option::ShippingOption, - shipping_query::ShippingQuery, - sticker::Sticker, - sticker_set::StickerSet, - successful_payment::SuccessfulPayment, - unit_true::True, - update::{Update, UpdateKind}, - user::User, - user_profile_photos::UserProfilePhotos, - venue::Venue, - video::Video, - video_note::VideoNote, - voice::Voice, - webhook_info::WebhookInfo, -}; +pub use animation::*; +pub use audio::*; +pub use callback_game::*; +pub use callback_query::*; +pub use chat::*; +pub use chat_action::*; +pub use chat_id::*; +pub use chat_member::*; +pub use chat_permissions::*; +pub use chat_photo::*; +pub use chosen_inline_result::*; +pub use contact::*; +pub use document::*; +pub use file::*; +pub use force_reply::*; +pub use game::*; +pub use game_high_score::*; +pub use inline_keyboard_button::*; +pub use inline_keyboard_markup::*; +pub use input_file::*; +pub use input_media::*; +pub use input_message_content::*; +pub use invoice::*; +pub use keyboard_button::*; +pub use label_price::*; +pub use location::*; +pub use login_url::*; +pub use mask_position::*; +pub use message::*; +pub use message_entity::*; +pub use order_info::*; +pub use parse_mode::*; +pub use photo_size::*; +pub use poll::*; +pub use pre_checkout_query::*; +pub use reply_keyboard_markup::*; +pub use reply_keyboard_remove::*; +pub use reply_markup::*; +pub use response_parameters::*; +pub use send_invoice::*; +pub use shipping_address::*; +pub use shipping_option::*; +pub use shipping_query::*; +pub use sticker::*; +pub use sticker_set::*; +pub use successful_payment::*; +pub use unit_true::*; +pub use update::*; +pub use user::*; +pub use user_profile_photos::*; +pub use venue::*; +pub use video::*; +pub use video_note::*; +pub use voice::*; +pub use webhook_info::*; + +pub use inline_query::*; +pub use inline_query_result::*; +pub use inline_query_result_article::*; +pub use inline_query_result_audio::*; +pub use inline_query_result_cached_audio::*; +pub use inline_query_result_cached_document::*; +pub use inline_query_result_cached_gif::*; +pub use inline_query_result_cached_mpeg4_gif::*; +pub use inline_query_result_cached_photo::*; +pub use inline_query_result_cached_sticker::*; +pub use inline_query_result_cached_video::*; +pub use inline_query_result_cached_voice::*; +pub use inline_query_result_contact::*; +pub use inline_query_result_document::*; +pub use inline_query_result_game::*; +pub use inline_query_result_gif::*; +pub use inline_query_result_location::*; +pub use inline_query_result_mpeg4_gif::*; +pub use inline_query_result_photo::*; +pub use inline_query_result_venue::*; +pub use inline_query_result_video::*; +pub use inline_query_result_voice::*; + +pub use encrypted_credintials::*; +pub use encrypted_passport_element::*; +pub use passport_data::*; +pub use passport_file::*; mod animation; mod audio; From 2b679fed43b59f81043de15eda6d5ddb1402582d Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 14:05:02 +0600 Subject: [PATCH 16/66] Fix a typo --- .../{encrypted_credintials.rs => encrypted_credentials.rs} | 0 src/types/encrypted_passport_element.rs | 2 +- src/types/mod.rs | 4 ++-- src/types/passport_data.rs | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) rename src/types/{encrypted_credintials.rs => encrypted_credentials.rs} (100%) diff --git a/src/types/encrypted_credintials.rs b/src/types/encrypted_credentials.rs similarity index 100% rename from src/types/encrypted_credintials.rs rename to src/types/encrypted_credentials.rs diff --git a/src/types/encrypted_passport_element.rs b/src/types/encrypted_passport_element.rs index 425ff429..5788d047 100644 --- a/src/types/encrypted_passport_element.rs +++ b/src/types/encrypted_passport_element.rs @@ -1,4 +1,4 @@ -use super::passport_file::PassportFile; +use super::PassportFile; #[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct EncryptedPassportElement { diff --git a/src/types/mod.rs b/src/types/mod.rs index ae62090e..62dbe9b9 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -79,7 +79,7 @@ pub use inline_query_result_venue::*; pub use inline_query_result_video::*; pub use inline_query_result_voice::*; -pub use encrypted_credintials::*; +pub use encrypted_credentials::*; pub use encrypted_passport_element::*; pub use passport_data::*; pub use passport_file::*; @@ -163,7 +163,7 @@ mod inline_query_result_venue; mod inline_query_result_video; mod inline_query_result_voice; -mod encrypted_credintials; +mod encrypted_credentials; mod encrypted_passport_element; mod passport_data; mod passport_file; diff --git a/src/types/passport_data.rs b/src/types/passport_data.rs index 8ca8e20c..4c938af8 100644 --- a/src/types/passport_data.rs +++ b/src/types/passport_data.rs @@ -1,5 +1,4 @@ -use super::encrypted_credintials::EncryptedCredentials; -use super::encrypted_passport_element::EncryptedPassportElement; +use super::{EncryptedCredentials, EncryptedPassportElement}; #[derive(Debug, Deserialize, Eq, Hash, PartialEq, Clone, Serialize)] pub struct PassportData { From 0ac725ac186a1e053d30274ab2b3d22a6c720e8e Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 20:34:13 +0600 Subject: [PATCH 17/66] Add AnswerCallbackQuery --- src/bot/api.rs | 11 +++ src/requests/answer_callback_query.rs | 122 ++++++++++++++++++++++++++ src/requests/mod.rs | 2 + 3 files changed, 135 insertions(+) create mode 100644 src/requests/answer_callback_query.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index ea3be1bc..a0dda9cf 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,4 +1,5 @@ use crate::bot::Bot; +use crate::requests::AnswerCallbackQuery; use crate::{ requests::{ AnswerPreCheckoutQuery, AnswerShippingQuery, EditMessageLiveLocation, @@ -274,4 +275,14 @@ impl Bot { { UnpinChatMessage::new(self, chat_id) } + + pub fn answer_callback_query<S>( + &self, + callback_query_id: S, + ) -> AnswerCallbackQuery + where + S: Into<String>, + { + AnswerCallbackQuery::new(self, callback_query_id) + } } diff --git a/src/requests/answer_callback_query.rs b/src/requests/answer_callback_query.rs new file mode 100644 index 00000000..600cb755 --- /dev/null +++ b/src/requests/answer_callback_query.rs @@ -0,0 +1,122 @@ +use crate::bot::Bot; +use crate::network; +use crate::requests::{Request, ResponseResult}; +use crate::types::True; +use async_trait::async_trait; + +/// Use this method to send answers to callback queries sent from inline +/// keyboards. The answer will be displayed to the user as a notification at the +/// top of the chat screen or as an alert. On success, True is returned. +/// +/// Alternatively, the user can be redirected to the specified Game URL. For +/// this option to work, you must first create a game for your bot via +/// @Botfather and accept the terms. Otherwise, you may use links like +/// t.me/your_bot?start=XXXX that open your bot with a parameter. +#[derive(Debug, Clone, Serialize)] +pub struct AnswerCallbackQuery<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + /// Unique identifier for the query to be answered. + callback_query_id: String, + + /// Text of the notification. If not specified, nothing will be shown to + /// the user, 0-200 characters + #[serde(skip_serializing_if = "Option::is_none")] + text: Option<String>, + + /// If true, an alert will be shown by the client instead of a notification + /// at the top of the chat screen. Defaults to false. + #[serde(skip_serializing_if = "Option::is_none")] + show_alert: Option<bool>, + + /// URL that will be opened by the user's client. If you have created a + /// Game and accepted the conditions via @Botfather, specify the URL that + /// opens your game – note that this will only work if the query comes from + /// a callback_game button. + #[serde(skip_serializing_if = "Option::is_none")] + url: Option<String>, + + /// The maximum amount of time in seconds that the result of the callback + /// query may be cached client-side. Telegram apps will support caching + /// starting in version 3.14. Defaults to 0. + #[serde(skip_serializing_if = "Option::is_none")] + cache_time: Option<i32>, +} + +#[async_trait] +impl Request for AnswerCallbackQuery<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl AnswerCallbackQuery<'_> { + pub async fn send(self) -> ResponseResult<True> { + network::request_json( + self.bot.client(), + self.bot.token(), + "answerCallbackQuery", + &self, + ) + .await + } +} + +impl<'a> AnswerCallbackQuery<'a> { + pub(crate) fn new<S>(bot: &'a Bot, callback_query_id: S) -> Self + where + S: Into<String>, + { + Self { + bot, + callback_query_id: callback_query_id.into(), + text: None, + show_alert: None, + url: None, + cache_time: None, + } + } + + pub fn callback_query_id<S>(mut self, value: S) -> Self + where + S: Into<String>, + { + self.callback_query_id = value.into(); + self + } + + pub fn text<S>(mut self, value: S) -> Self + where + S: Into<String>, + { + self.text = Some(value.into()); + self + } + + pub fn show_alert<B>(mut self, value: B) -> Self + where + B: Into<bool>, + { + self.show_alert = Some(value.into()); + self + } + + pub fn url<S>(mut self, value: S) -> Self + where + S: Into<String>, + { + self.url = Some(value.into()); + self + } + + pub fn cache_time<I>(mut self, value: I) -> Self + where + I: Into<i32>, + { + self.cache_time = Some(value.into()); + self + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index a1ecef59..ec4b8232 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -3,6 +3,7 @@ use async_trait::async_trait; use serde::de::DeserializeOwned; +pub use answer_callback_query::*; pub use answer_pre_checkout_query::*; pub use answer_shipping_query::*; pub use edit_message_live_location::*; @@ -37,6 +38,7 @@ pub use unpin_chat_message::*; mod form_builder; mod utils; +mod answer_callback_query; mod answer_pre_checkout_query; mod answer_shipping_query; mod edit_message_live_location; From 6f28f28a4ef0d173dbcb38b3bb2339e877251568 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 20:51:09 +0600 Subject: [PATCH 18/66] Add DeleteChatStickerSet --- src/bot/api.rs | 9 +++- src/requests/delete_chat_sticker_set.rs | 61 +++++++++++++++++++++++++ src/requests/mod.rs | 2 + 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/requests/delete_chat_sticker_set.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index a0dda9cf..05704df2 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,5 +1,5 @@ use crate::bot::Bot; -use crate::requests::AnswerCallbackQuery; +use crate::requests::{AnswerCallbackQuery, DeleteChatStickerSet}; use crate::{ requests::{ AnswerPreCheckoutQuery, AnswerShippingQuery, EditMessageLiveLocation, @@ -285,4 +285,11 @@ impl Bot { { AnswerCallbackQuery::new(self, callback_query_id) } + + pub fn delete_chat_sticker_set<C>(&self, chat_id: C) -> DeleteChatStickerSet + where + C: Into<ChatId>, + { + DeleteChatStickerSet::new(self, chat_id) + } } diff --git a/src/requests/delete_chat_sticker_set.rs b/src/requests/delete_chat_sticker_set.rs new file mode 100644 index 00000000..abb64fb6 --- /dev/null +++ b/src/requests/delete_chat_sticker_set.rs @@ -0,0 +1,61 @@ +use crate::bot::Bot; +use crate::network; +use crate::requests::{Request, ResponseResult}; +use crate::types::{ChatId, True}; +use async_trait::async_trait; + +/// Use this method to delete a group sticker set from a supergroup. The bot +/// must be an administrator in the chat for this to work and must have the +/// appropriate admin rights. Use the field can_set_sticker_set optionally +/// returned in getChat requests to check if the bot can use this method. +/// Returns True on success. +#[derive(Debug, Clone, Serialize)] +pub struct DeleteChatStickerSet<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername) + chat_id: ChatId, +} + +#[async_trait] +impl Request for DeleteChatStickerSet<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl DeleteChatStickerSet<'_> { + async fn send(&self) -> ResponseResult<True> { + network::request_json( + self.bot.client(), + self.bot.token(), + "deleteChatStickerSet", + &self, + ) + .await + } +} + +impl<'a> DeleteChatStickerSet<'a> { + pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self + where + C: Into<ChatId>, + { + Self { + bot, + chat_id: chat_id.into(), + } + } + + pub fn chat_id<C>(mut self, value: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = value.into(); + self + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index ec4b8232..b5790585 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -6,6 +6,7 @@ use serde::de::DeserializeOwned; pub use answer_callback_query::*; pub use answer_pre_checkout_query::*; pub use answer_shipping_query::*; +pub use delete_chat_sticker_set::*; pub use edit_message_live_location::*; pub use forward_message::*; pub use get_chat::*; @@ -41,6 +42,7 @@ mod utils; mod answer_callback_query; mod answer_pre_checkout_query; mod answer_shipping_query; +mod delete_chat_sticker_set; mod edit_message_live_location; mod forward_message; mod get_chat; From 82db9b18b244fe5d2486b6a9d3521a58968e82fc Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 20:56:58 +0600 Subject: [PATCH 19/66] Add SetChatStickerSet --- src/bot/api.rs | 16 +++++- src/requests/mod.rs | 2 + src/requests/set_chat_sticker_set.rs | 78 ++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/requests/set_chat_sticker_set.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index 05704df2..dae00bdb 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,5 +1,7 @@ use crate::bot::Bot; -use crate::requests::{AnswerCallbackQuery, DeleteChatStickerSet}; +use crate::requests::{ + AnswerCallbackQuery, DeleteChatStickerSet, SetChatStickerSet, +}; use crate::{ requests::{ AnswerPreCheckoutQuery, AnswerShippingQuery, EditMessageLiveLocation, @@ -292,4 +294,16 @@ impl Bot { { DeleteChatStickerSet::new(self, chat_id) } + + pub fn set_chat_sticker_set<C, S>( + &self, + chat_id: C, + sticker_set_name: S, + ) -> SetChatStickerSet + where + C: Into<ChatId>, + S: Into<String>, + { + SetChatStickerSet::new(self, chat_id, sticker_set_name) + } } diff --git a/src/requests/mod.rs b/src/requests/mod.rs index b5790585..ef012de8 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -32,6 +32,7 @@ pub use send_venue::*; pub use send_video::*; pub use send_video_note::*; pub use send_voice::*; +pub use set_chat_sticker_set::*; pub use stop_message_live_location::*; pub use unban_chat_member::*; pub use unpin_chat_message::*; @@ -68,6 +69,7 @@ mod send_venue; mod send_video; mod send_video_note; mod send_voice; +mod set_chat_sticker_set; mod stop_message_live_location; mod unban_chat_member; mod unpin_chat_message; diff --git a/src/requests/set_chat_sticker_set.rs b/src/requests/set_chat_sticker_set.rs new file mode 100644 index 00000000..14927d0d --- /dev/null +++ b/src/requests/set_chat_sticker_set.rs @@ -0,0 +1,78 @@ +use crate::bot::Bot; +use crate::network; +use crate::requests::{Request, ResponseResult}; +use crate::types::{ChatId, True}; +use async_trait::async_trait; + +/// Use this method to set a new group sticker set for a supergroup. The bot +/// must be an administrator in the chat for this to work and must have the +/// appropriate admin rights. Use the field can_set_sticker_set optionally +/// returned in getChat requests to check if the bot can use this method. +/// Returns True on success. +#[derive(Debug, Clone, Serialize)] +pub struct SetChatStickerSet<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + /// Unique identifier for the target chat or username of the target + /// supergroup (in the format @supergroupusername) + chat_id: ChatId, + + /// Name of the sticker set to be set as the group sticker set + sticker_set_name: String, +} + +#[async_trait] +impl Request for SetChatStickerSet<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl SetChatStickerSet<'_> { + async fn send(&self) -> ResponseResult<True> { + network::request_json( + self.bot.client(), + self.bot.token(), + "setChatStickerSet", + &self, + ) + .await + } +} + +impl<'a> SetChatStickerSet<'a> { + pub(crate) fn new<C, S>( + bot: &'a Bot, + chat_id: C, + sticker_set_name: S, + ) -> Self + where + C: Into<ChatId>, + S: Into<String>, + { + Self { + bot, + chat_id: chat_id.into(), + sticker_set_name: sticker_set_name.into(), + } + } + + pub fn chat_id<C>(mut self, value: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = value.into(); + self + } + + pub fn sticker_set_name<S>(mut self, value: S) -> Self + where + S: Into<String>, + { + self.sticker_set_name = value.into(); + self + } +} From 21952b149a5d21be9cdac926ea6891842edea582 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Thu, 17 Oct 2019 18:01:39 +0300 Subject: [PATCH 20/66] add method setChatDescription --- src/bot/api.rs | 9 ++- src/requests/mod.rs | 2 + src/requests/set_chat_description.rs | 96 ++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/requests/set_chat_description.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index ea3be1bc..38783960 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -6,7 +6,7 @@ use crate::{ PinChatMessage, PromoteChatMember, RestrictChatMember, SendAudio, SendChatAction, SendContact, SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideoNote, SendVoice, - StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, + SetChatDescription, StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -256,6 +256,13 @@ impl Bot { SendVoice::new(self, chat_id, voice) } + pub fn send_chat_description<C>(&self, chat_id: C) -> SetChatDescription + where + C: Into<ChatId>, + { + SetChatDescription::new(self, chat_id) + } + pub fn unban_chat_member<C, U>( &self, chat_id: C, diff --git a/src/requests/mod.rs b/src/requests/mod.rs index a1ecef59..73f09876 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -30,6 +30,7 @@ pub use send_venue::*; pub use send_video::*; pub use send_video_note::*; pub use send_voice::*; +pub use set_chat_description::*; pub use stop_message_live_location::*; pub use unban_chat_member::*; pub use unpin_chat_message::*; @@ -64,6 +65,7 @@ mod send_venue; mod send_video; mod send_video_note; mod send_voice; +mod set_chat_description; mod stop_message_live_location; mod unban_chat_member; mod unpin_chat_message; diff --git a/src/requests/set_chat_description.rs b/src/requests/set_chat_description.rs new file mode 100644 index 00000000..8a087405 --- /dev/null +++ b/src/requests/set_chat_description.rs @@ -0,0 +1,96 @@ +use async_trait::async_trait; + +use crate::{ + network, + requests::{Request, ResponseResult}, + types::{True, ChatId}, + bot::Bot, +}; + +#[derive(Debug, Clone, Serialize)] +pub struct SetChatDescription<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + chat_id: ChatId, + #[serde(skip_serializing_if = "Option::is_none")] + description: Option<String>, +} + +#[async_trait] +impl Request for SetChatDescription<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl SetChatDescription<'_> { + pub async fn send(self) -> ResponseResult<True> { + network::request_json( + &self.bot.client(), + &self.bot.token(), + "setChatDescription", + &self + ).await + } +} + +impl<'a> SetChatDescription<'a> { + pub(crate) fn new<C>( + bot: &'a Bot, + chat_id: C, + ) -> Self + where C: Into<ChatId> + { + Self { + bot, + chat_id: chat_id.into(), + description: None + } + } + + pub fn chat_id<T>(mut self, chat_id: T) -> Self + where T: Into<ChatId> + { + self.chat_id = chat_id.into(); + self + } + + pub fn description<T>(mut self, description: T) -> Self + where T: Into<String> + { + self.description = Some(description.into()); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize_new() { + let bot = Bot::new("token"); + let chat_id = 123; + let method = SetChatDescription::new(&bot, chat_id); + + let expected = r#"{"chat_id":123}"#; + let actual = serde_json::to_string::<SetChatDescription>(&method).unwrap(); + assert_eq!(actual, expected); + } + + #[test] + fn serialize_description() { + let bot = Bot::new("token"); + let chat_id = 123; + let description = "description"; + let method = SetChatDescription::new(&bot, chat_id) + .description(description); + + let expected = r#"{"chat_id":123,"description":"description"}"#; + let actual = serde_json::to_string::<SetChatDescription>(&method).unwrap(); + assert_eq!(actual, expected); + } +} From b3572072ada1840ef64c4b8034bddc7b14e56da7 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 21:09:46 +0600 Subject: [PATCH 21/66] Add GetChatMember --- src/bot/api.rs | 10 ++++- src/requests/get_chat_member.rs | 71 +++++++++++++++++++++++++++++++++ src/requests/mod.rs | 2 + 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/requests/get_chat_member.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index dae00bdb..7eec264c 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,6 +1,6 @@ use crate::bot::Bot; use crate::requests::{ - AnswerCallbackQuery, DeleteChatStickerSet, SetChatStickerSet, + AnswerCallbackQuery, DeleteChatStickerSet, GetChatMember, SetChatStickerSet, }; use crate::{ requests::{ @@ -306,4 +306,12 @@ impl Bot { { SetChatStickerSet::new(self, chat_id, sticker_set_name) } + + pub fn get_chat_member<C, I>(&self, chat_id: C, user_id: I) -> GetChatMember + where + C: Into<ChatId>, + I: Into<i32>, + { + GetChatMember::new(self, chat_id, user_id) + } } diff --git a/src/requests/get_chat_member.rs b/src/requests/get_chat_member.rs new file mode 100644 index 00000000..293db180 --- /dev/null +++ b/src/requests/get_chat_member.rs @@ -0,0 +1,71 @@ +use crate::bot::Bot; +use crate::network; +use crate::requests::{Request, ResponseResult}; +use crate::types::{ChatId, ChatMember}; +use async_trait::async_trait; + +/// Use this method to get information about a member of a chat. Returns a +/// ChatMember object on success. +#[derive(Debug, Clone, Serialize)] +pub struct GetChatMember<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + /// Unique identifier for the target chat or username of the target + /// supergroup or channel (in the format @channelusername) + chat_id: ChatId, + + /// Unique identifier of the target user + user_id: i32, +} + +#[async_trait] +impl Request for GetChatMember<'_> { + type Output = ChatMember; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl GetChatMember<'_> { + async fn send(&self) -> ResponseResult<ChatMember> { + network::request_json( + self.bot.client(), + self.bot.token(), + "getChatMember", + &self, + ) + .await + } +} + +impl<'a> GetChatMember<'a> { + pub(crate) fn new<C, I>(bot: &'a Bot, chat_id: C, user_id: I) -> Self + where + C: Into<ChatId>, + I: Into<i32>, + { + Self { + bot, + chat_id: chat_id.into(), + user_id: user_id.into(), + } + } + + pub fn chat_id<C>(mut self, value: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = value.into(); + self + } + + pub fn user_id<I>(mut self, value: I) -> Self + where + I: Into<i32>, + { + self.user_id = value.into(); + self + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index ef012de8..a6664eec 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -10,6 +10,7 @@ pub use delete_chat_sticker_set::*; pub use edit_message_live_location::*; pub use forward_message::*; pub use get_chat::*; +pub use get_chat_member::*; pub use get_file::*; pub use get_me::*; pub use get_updates::*; @@ -47,6 +48,7 @@ mod delete_chat_sticker_set; mod edit_message_live_location; mod forward_message; mod get_chat; +mod get_chat_member; mod get_file; mod get_me; mod get_updates; From 12d944aeb7b325132678e3a6d227228b7f11a837 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 21:13:50 +0600 Subject: [PATCH 22/66] Add GetChatMembersCount --- src/bot/api.rs | 10 ++++- src/requests/get_chat_members_count.rs | 61 ++++++++++++++++++++++++++ src/requests/mod.rs | 2 + 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/requests/get_chat_members_count.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index 7eec264c..ae1c26d9 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,6 +1,7 @@ use crate::bot::Bot; use crate::requests::{ - AnswerCallbackQuery, DeleteChatStickerSet, GetChatMember, SetChatStickerSet, + AnswerCallbackQuery, DeleteChatStickerSet, GetChatMember, + GetChatMembersCount, SetChatStickerSet, }; use crate::{ requests::{ @@ -314,4 +315,11 @@ impl Bot { { GetChatMember::new(self, chat_id, user_id) } + + pub fn get_chat_members_count<C>(&self, chat_id: C) -> GetChatMembersCount + where + C: Into<ChatId>, + { + GetChatMembersCount::new(self, chat_id) + } } diff --git a/src/requests/get_chat_members_count.rs b/src/requests/get_chat_members_count.rs new file mode 100644 index 00000000..3595cf49 --- /dev/null +++ b/src/requests/get_chat_members_count.rs @@ -0,0 +1,61 @@ +use async_trait::async_trait; + +use crate::bot::Bot; +use crate::{ + network, + requests::{Request, ResponseResult}, + types::{Chat, ChatId}, +}; + +/// Use this method to get the number of members in a chat. Returns Int on +/// success. +#[derive(Debug, Clone, Serialize)] +pub struct GetChatMembersCount<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + /// Unique identifier for the target chat or username + /// of the target supergroup or channel (in the format @channelusername) + chat_id: ChatId, +} + +#[async_trait] +impl Request for GetChatMembersCount<'_> { + type Output = Chat; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl GetChatMembersCount<'_> { + pub async fn send(self) -> ResponseResult<Chat> { + network::request_json( + self.bot.client(), + self.bot.token(), + "getChatMembersCount", + &self, + ) + .await + } +} + +impl<'a> GetChatMembersCount<'a> { + pub fn new<C>(bot: &'a Bot, chat_id: C) -> Self + where + C: Into<ChatId>, + { + Self { + bot, + chat_id: chat_id.into(), + } + } + + pub fn chat_id<C>(mut self, value: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = value.into(); + self + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index a6664eec..4bef49d3 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -11,6 +11,7 @@ pub use edit_message_live_location::*; pub use forward_message::*; pub use get_chat::*; pub use get_chat_member::*; +pub use get_chat_members_count::*; pub use get_file::*; pub use get_me::*; pub use get_updates::*; @@ -49,6 +50,7 @@ mod edit_message_live_location; mod forward_message; mod get_chat; mod get_chat_member; +mod get_chat_members_count; mod get_file; mod get_me; mod get_updates; From 36976e098d56acfa3ad3d695b4f0f3462c5ee88e Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Thu, 17 Oct 2019 18:36:03 +0300 Subject: [PATCH 23/66] changed where necessary String to InputFile --- src/bot/api.rs | 4 ++-- src/requests/send_animation.rs | 9 ++++----- src/requests/send_document.rs | 14 ++++++-------- src/requests/send_video.rs | 13 ++++++------- src/requests/send_video_note.rs | 14 ++++++-------- src/requests/send_voice.rs | 9 ++++----- 6 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index 38783960..a7c6791c 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -243,7 +243,7 @@ impl Bot { ) -> SendVideoNote where C: Into<ChatId>, - V: Into<String>, // TODO: InputFile + V: Into<InputFile>, { SendVideoNote::new(self, chat_id, video_note) } @@ -251,7 +251,7 @@ impl Bot { pub fn send_voice<C, V>(&self, chat_id: C, voice: V) -> SendVoice where C: Into<ChatId>, - V: Into<String>, // TODO: InputFile + V: Into<InputFile>, { SendVoice::new(self, chat_id, voice) } diff --git a/src/requests/send_animation.rs b/src/requests/send_animation.rs index a509e6dc..1f70465f 100644 --- a/src/requests/send_animation.rs +++ b/src/requests/send_animation.rs @@ -3,7 +3,7 @@ use async_trait::async_trait; use crate::bot::Bot; use crate::network; use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; +use crate::types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}; ///TODO: add to bot api ///Use this method to send animation files (GIF or H.264/MPEG-4 AVC video @@ -21,8 +21,7 @@ pub struct SendAnimation<'a> { /// exists on the Telegram servers (recommended), pass an HTTP URL as a /// String for Telegram to get an animation from the Internet, or upload a /// new animation using multipart/form-data. More info on Sending Files » - pub animation: String, - // InputFile or String + pub animation: InputFile, ///Duration of sent animation in seconds #[serde(skip_serializing_if = "Option::is_none")] pub duration: Option<u64>, @@ -90,7 +89,7 @@ impl<'a> SendAnimation<'a> { pub(crate) fn new<C, S>(bot: &'a Bot, chat_id: C, animation: S) -> Self where C: Into<ChatId>, - S: Into<String>, + S: Into<InputFile>, { Self { bot, @@ -140,7 +139,7 @@ impl<'a> SendAnimation<'a> { } pub fn thumb<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.thumb = Some(value.into()); self diff --git a/src/requests/send_document.rs b/src/requests/send_document.rs index 93c5dc5b..6980120b 100644 --- a/src/requests/send_document.rs +++ b/src/requests/send_document.rs @@ -4,7 +4,7 @@ use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, - types::{ChatId, Message, ParseMode, ReplyMarkup}, + types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}, }; // TODO: add method to bot/api @@ -23,8 +23,7 @@ pub struct SendDocument<'a> { /// the Telegram servers (recommended), pass an HTTP URL as a String for /// Telegram to get a file from the Internet, or upload a new one using /// multipart/form-data.» - pub document: String, - //InputFile or String + pub document: InputFile, /// Thumbnail of the file sent; can be ignored if thumbnail generation for /// the file is supported server-side. The thumbnail should be in JPEG /// format and less than 200 kB in size. A thumbnail‘s width and height @@ -34,8 +33,7 @@ pub struct SendDocument<'a> { /// if the thumbnail was uploaded using multipart/form-data under /// <file_attach_name>. More info on Sending Files » #[serde(skip_serializing_if = "Option::is_none")] - pub thumb: Option<String>, - //InputFile or String + pub thumb: Option<InputFile>, /// Document caption (may also be used when resending documents by /// file_id), 0-1024 characters #[serde(skip_serializing_if = "Option::is_none")] @@ -83,7 +81,7 @@ impl<'a> SendDocument<'a> { pub(crate) fn new<C, D>(bot: &'a Bot, chat_id: C, document: D) -> Self where C: Into<ChatId>, - D: Into<String>, + D: Into<InputFile>, { Self { bot, @@ -108,7 +106,7 @@ impl<'a> SendDocument<'a> { pub fn document<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.document = value.into(); self @@ -116,7 +114,7 @@ impl<'a> SendDocument<'a> { pub fn thumb<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.thumb = Some(value.into()); self diff --git a/src/requests/send_video.rs b/src/requests/send_video.rs index e6ab5712..e1f5fc54 100644 --- a/src/requests/send_video.rs +++ b/src/requests/send_video.rs @@ -3,7 +3,7 @@ use async_trait::async_trait; use crate::bot::Bot; use crate::network; use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, Message, ParseMode, ReplyMarkup}; +use crate::types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}; //TODO: add action to bot api ///Use this method to send video files, Telegram clients support mp4 videos @@ -21,7 +21,7 @@ pub struct SendVideo<'a> { /// the Telegram servers (recommended), pass an HTTP URL as a String for /// Telegram to get a video from the Internet, or upload a new video using /// multipart/form-data. More info on Sending Files » - pub video: String, + pub video: InputFile, ///Duration of sent video in seconds #[serde(skip_serializing_if = "Option::is_none")] pub duration: Option<u64>, @@ -40,8 +40,7 @@ pub struct SendVideo<'a> { /// if the thumbnail was uploaded using multipart/form-data under /// <file_attach_name>. More info on Sending Files » #[serde(skip_serializing_if = "Option::is_none")] - pub thumb: Option<String>, - //InputFile or String + pub thumb: Option<InputFile>, ///Video caption (may also be used when resending videos by file_id), /// 0-1024 characters #[serde(skip_serializing_if = "Option::is_none")] @@ -92,7 +91,7 @@ impl<'a> SendVideo<'a> { pub(crate) fn new<C, V>(bot: &'a Bot, chat_id: C, video: V) -> Self where C: Into<ChatId>, - V: Into<String>, + V: Into<InputFile>, { Self { bot, @@ -120,7 +119,7 @@ impl<'a> SendVideo<'a> { pub fn video<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.video = value.into(); self @@ -149,7 +148,7 @@ impl<'a> SendVideo<'a> { } pub fn thumb<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.thumb = Some(value.into()); self diff --git a/src/requests/send_video_note.rs b/src/requests/send_video_note.rs index bd3eb316..7d580f64 100644 --- a/src/requests/send_video_note.rs +++ b/src/requests/send_video_note.rs @@ -4,7 +4,7 @@ use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, - types::{ChatId, Message, ReplyMarkup}, + types::{ChatId, Message, ReplyMarkup, InputFile}, }; ///As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 @@ -21,8 +21,7 @@ pub struct SendVideoNote<'a> { /// exists on the Telegram servers (recommended) or upload a new video /// using multipart/form-data. More info on Sending Files ». Sending video /// notes by a URL is currently unsupported - pub video_note: String, - // InputFile or String + pub video_note: InputFile, ///Duration of sent video in seconds #[serde(skip_serializing_if = "Option::is_none")] pub duration: Option<u64>, @@ -38,8 +37,7 @@ pub struct SendVideoNote<'a> { /// if the thumbnail was uploaded using multipart/form-data under /// <file_attach_name>. More info on Sending Files » #[serde(skip_serializing_if = "Option::is_none")] - pub thumb: Option<String>, - // InputFile or String + pub thumb: Option<InputFile>, ///Sends the message silently. Users will receive a notification with no /// sound. #[serde(skip_serializing_if = "Option::is_none")] @@ -79,7 +77,7 @@ impl<'a> SendVideoNote<'a> { pub(crate) fn new<C, V>(bot: &'a Bot, chat_id: C, video_note: V) -> Self where C: Into<ChatId>, - V: Into<String>, + V: Into<InputFile>, { Self { bot, @@ -104,7 +102,7 @@ impl<'a> SendVideoNote<'a> { pub fn video_note<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.video_note = value.into(); self @@ -128,7 +126,7 @@ impl<'a> SendVideoNote<'a> { pub fn thumb<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.thumb = Some(value.into()); self diff --git a/src/requests/send_voice.rs b/src/requests/send_voice.rs index b591defc..184060a4 100644 --- a/src/requests/send_voice.rs +++ b/src/requests/send_voice.rs @@ -4,7 +4,7 @@ use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, - types::{ChatId, Message, ParseMode, ReplyMarkup}, + types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}, }; ///Use this method to send audio files, if you want Telegram clients to display @@ -24,8 +24,7 @@ pub struct SendVoice<'a> { /// on the Telegram servers (recommended), pass an HTTP URL as a String for /// Telegram to get a file from the Internet, or upload a new one using /// multipart/form-data. More info on Sending Files » - pub voice: String, - //InputFile or String + pub voice: InputFile, /// Voice message caption, 0-1024 characters #[serde(skip_serializing_if = "Option::is_none")] pub caption: Option<String>, @@ -76,7 +75,7 @@ impl<'a> SendVoice<'a> { pub(crate) fn new<C, V>(bot: &'a Bot, chat_id: C, voice: V) -> Self where C: Into<ChatId>, - V: Into<String>, + V: Into<InputFile>, { Self { bot, @@ -101,7 +100,7 @@ impl<'a> SendVoice<'a> { pub fn voice<T>(mut self, value: T) -> Self where - T: Into<String>, + T: Into<InputFile>, { self.voice = value.into(); self From f2cd6278fb52eb7b5a41d0af8a587c9e16431bbb Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Thu, 17 Oct 2019 18:44:34 +0300 Subject: [PATCH 24/66] changed where necessary String to InputFile --- src/requests/send_animation.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/requests/send_animation.rs b/src/requests/send_animation.rs index 1f70465f..c7932270 100644 --- a/src/requests/send_animation.rs +++ b/src/requests/send_animation.rs @@ -40,8 +40,7 @@ pub struct SendAnimation<'a> { /// if the thumbnail was uploaded using multipart/form-data under /// <file_attach_name> » #[serde(skip_serializing_if = "Option::is_none")] - pub thumb: Option<String>, - // InputFile or String Optional + pub thumb: Option<InputFile>, ///Animation caption (may also be used when resending animation by /// file_id), 0-1024 characters #[serde(skip_serializing_if = "Option::is_none")] From 852b89be8815bf5522c46a3921c87a981096de9b Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 22:16:00 +0600 Subject: [PATCH 25/66] Add the missing methods to Bot (bot/api.h) --- src/bot/api.rs | 34 +++++++++++++++++++++++++-- src/requests/mod.rs | 4 ++-- src/requests/send_animation.rs | 3 +-- src/requests/send_document.rs | 4 +--- src/requests/send_video.rs | 3 +-- src/requests/send_video_note.rs | 2 +- src/requests/send_voice.rs | 2 +- src/requests/set_chat_description.rs | 35 +++++++++++++++------------- 8 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index 4e9bf065..67a0a9bc 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,7 +1,8 @@ use crate::bot::Bot; use crate::requests::{ AnswerCallbackQuery, DeleteChatStickerSet, GetChatMember, - GetChatMembersCount, SetChatStickerSet, + GetChatMembersCount, SendAnimation, SendDocument, SendVideo, + SetChatStickerSet, }; use crate::{ requests::{ @@ -10,7 +11,8 @@ use crate::{ PinChatMessage, PromoteChatMember, RestrictChatMember, SendAudio, SendChatAction, SendContact, SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideoNote, SendVoice, - SetChatDescription, StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, + SetChatDescription, StopMessageLiveLocation, UnbanChatMember, + UnpinChatMessage, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -329,4 +331,32 @@ impl Bot { { GetChatMembersCount::new(self, chat_id) } + + pub fn send_video<C, V>(&self, chat_id: C, video: V) -> SendVideo + where + C: Into<ChatId>, + V: Into<InputFile>, + { + SendVideo::new(self, chat_id, video) + } + + pub fn send_document<C, D>(&self, chat_id: C, document: D) -> SendDocument + where + C: Into<ChatId>, + D: Into<InputFile>, + { + SendDocument::new(self, chat_id, document) + } + + pub fn send_animation<C, S>( + &self, + chat_id: C, + animation: S, + ) -> SendAnimation + where + C: Into<ChatId>, + S: Into<InputFile>, + { + SendAnimation::new(self, chat_id, animation) + } } diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 993200cf..d2ee64f9 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -34,8 +34,8 @@ pub use send_venue::*; pub use send_video::*; pub use send_video_note::*; pub use send_voice::*; -pub use set_chat_sticker_set::*; pub use set_chat_description::*; +pub use set_chat_sticker_set::*; pub use stop_message_live_location::*; pub use unban_chat_member::*; pub use unpin_chat_message::*; @@ -74,8 +74,8 @@ mod send_venue; mod send_video; mod send_video_note; mod send_voice; -mod set_chat_sticker_set; mod set_chat_description; +mod set_chat_sticker_set; mod stop_message_live_location; mod unban_chat_member; mod unpin_chat_message; diff --git a/src/requests/send_animation.rs b/src/requests/send_animation.rs index c7932270..279eafff 100644 --- a/src/requests/send_animation.rs +++ b/src/requests/send_animation.rs @@ -3,9 +3,8 @@ use async_trait::async_trait; use crate::bot::Bot; use crate::network; use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}; +use crate::types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}; -///TODO: add to bot api ///Use this method to send animation files (GIF or H.264/MPEG-4 AVC video /// without sound). On success, the sent Message is returned. Bots can currently /// send animation files of up to 50 MB in size, this limit may be changed in diff --git a/src/requests/send_document.rs b/src/requests/send_document.rs index 6980120b..5c4af3af 100644 --- a/src/requests/send_document.rs +++ b/src/requests/send_document.rs @@ -4,11 +4,9 @@ use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, - types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}, + types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, }; -// TODO: add method to bot/api - ///Use this method to send general files. On success, the sent Message is /// returned. Bots can currently send files of any type of up to 50 MB in size, /// this limit may be changed in the future. diff --git a/src/requests/send_video.rs b/src/requests/send_video.rs index e1f5fc54..85b5d27a 100644 --- a/src/requests/send_video.rs +++ b/src/requests/send_video.rs @@ -3,9 +3,8 @@ use async_trait::async_trait; use crate::bot::Bot; use crate::network; use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}; +use crate::types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}; -//TODO: add action to bot api ///Use this method to send video files, Telegram clients support mp4 videos /// (other formats may be sent as Document). On success, the sent Message is /// returned. Bots can currently send video files of up to 50 MB in size, this diff --git a/src/requests/send_video_note.rs b/src/requests/send_video_note.rs index 7d580f64..c506058a 100644 --- a/src/requests/send_video_note.rs +++ b/src/requests/send_video_note.rs @@ -4,7 +4,7 @@ use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, - types::{ChatId, Message, ReplyMarkup, InputFile}, + types::{ChatId, InputFile, Message, ReplyMarkup}, }; ///As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 diff --git a/src/requests/send_voice.rs b/src/requests/send_voice.rs index 184060a4..9f152d02 100644 --- a/src/requests/send_voice.rs +++ b/src/requests/send_voice.rs @@ -4,7 +4,7 @@ use crate::bot::Bot; use crate::{ network, requests::{Request, ResponseResult}, - types::{ChatId, Message, ParseMode, ReplyMarkup, InputFile}, + types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, }; ///Use this method to send audio files, if you want Telegram clients to display diff --git a/src/requests/set_chat_description.rs b/src/requests/set_chat_description.rs index 8a087405..e3cf9c68 100644 --- a/src/requests/set_chat_description.rs +++ b/src/requests/set_chat_description.rs @@ -1,10 +1,10 @@ use async_trait::async_trait; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, - types::{True, ChatId}, - bot::Bot, + types::{ChatId, True}, }; #[derive(Debug, Clone, Serialize)] @@ -32,34 +32,35 @@ impl SetChatDescription<'_> { &self.bot.client(), &self.bot.token(), "setChatDescription", - &self - ).await + &self, + ) + .await } } impl<'a> SetChatDescription<'a> { - pub(crate) fn new<C>( - bot: &'a Bot, - chat_id: C, - ) -> Self - where C: Into<ChatId> + pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self + where + C: Into<ChatId>, { Self { bot, chat_id: chat_id.into(), - description: None + description: None, } } pub fn chat_id<T>(mut self, chat_id: T) -> Self - where T: Into<ChatId> + where + T: Into<ChatId>, { self.chat_id = chat_id.into(); self } pub fn description<T>(mut self, description: T) -> Self - where T: Into<String> + where + T: Into<String>, { self.description = Some(description.into()); self @@ -77,7 +78,8 @@ mod tests { let method = SetChatDescription::new(&bot, chat_id); let expected = r#"{"chat_id":123}"#; - let actual = serde_json::to_string::<SetChatDescription>(&method).unwrap(); + let actual = + serde_json::to_string::<SetChatDescription>(&method).unwrap(); assert_eq!(actual, expected); } @@ -86,11 +88,12 @@ mod tests { let bot = Bot::new("token"); let chat_id = 123; let description = "description"; - let method = SetChatDescription::new(&bot, chat_id) - .description(description); + let method = + SetChatDescription::new(&bot, chat_id).description(description); let expected = r#"{"chat_id":123,"description":"description"}"#; - let actual = serde_json::to_string::<SetChatDescription>(&method).unwrap(); + let actual = + serde_json::to_string::<SetChatDescription>(&method).unwrap(); assert_eq!(actual, expected); } } From ceaf36b1013174ab4b377cf1ad7824e1a348637e Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Thu, 17 Oct 2019 22:16:55 +0600 Subject: [PATCH 26/66] Merge imports by default (rustfmt.toml) --- rustfmt.toml | 3 ++- src/bot/api.rs | 21 +++++++++------------ src/bot/download.rs | 3 +-- src/dispatcher/handler.rs | 3 +-- src/dispatcher/simple/error_policy.rs | 4 +--- src/dispatcher/simple/mod.rs | 9 +++++---- src/dispatcher/updater.rs | 3 +-- src/requests/answer_callback_query.rs | 10 ++++++---- src/requests/answer_pre_checkout_query.rs | 2 +- src/requests/answer_shipping_query.rs | 2 +- src/requests/delete_chat_sticker_set.rs | 10 ++++++---- src/requests/edit_message_live_location.rs | 2 +- src/requests/form_builder.rs | 3 +-- src/requests/forward_message.rs | 2 +- src/requests/get_chat.rs | 2 +- src/requests/get_chat_member.rs | 10 ++++++---- src/requests/get_chat_members_count.rs | 2 +- src/requests/get_file.rs | 2 +- src/requests/get_me.rs | 2 +- src/requests/get_updates.rs | 2 +- src/requests/get_user_profile_photos.rs | 2 +- src/requests/kick_chat_member.rs | 2 +- src/requests/pin_chat_message.rs | 2 +- src/requests/promote_chat_member.rs | 2 +- src/requests/restrict_chat_member.rs | 2 +- src/requests/send_animation.rs | 10 ++++++---- src/requests/send_audio.rs | 2 +- src/requests/send_chat_action.rs | 2 +- src/requests/send_contact.rs | 2 +- src/requests/send_document.rs | 2 +- src/requests/send_location.rs | 2 +- src/requests/send_media_group.rs | 2 +- src/requests/send_message.rs | 2 +- src/requests/send_photo.rs | 2 +- src/requests/send_poll.rs | 2 +- src/requests/send_venue.rs | 2 +- src/requests/send_video.rs | 10 ++++++---- src/requests/send_video_note.rs | 2 +- src/requests/send_voice.rs | 2 +- src/requests/set_chat_sticker_set.rs | 10 ++++++---- src/requests/stop_message_live_location.rs | 2 +- src/requests/unban_chat_member.rs | 2 +- src/requests/unpin_chat_message.rs | 2 +- src/types/inline_query_result.rs | 3 +-- src/types/message.rs | 3 +-- src/types/unit_true.rs | 6 ++++-- 46 files changed, 92 insertions(+), 87 deletions(-) diff --git a/rustfmt.toml b/rustfmt.toml index f99a2b6f..cee9b586 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,5 @@ format_code_in_doc_comments = true wrap_comments = true format_strings = true -max_width = 80 \ No newline at end of file +max_width = 80 +merge_imports = true \ No newline at end of file diff --git a/src/bot/api.rs b/src/bot/api.rs index 67a0a9bc..924e7abc 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -1,17 +1,14 @@ -use crate::bot::Bot; -use crate::requests::{ - AnswerCallbackQuery, DeleteChatStickerSet, GetChatMember, - GetChatMembersCount, SendAnimation, SendDocument, SendVideo, - SetChatStickerSet, -}; use crate::{ + bot::Bot, requests::{ - AnswerPreCheckoutQuery, AnswerShippingQuery, EditMessageLiveLocation, - ForwardMessage, GetFile, GetMe, GetUpdates, KickChatMember, - PinChatMessage, PromoteChatMember, RestrictChatMember, SendAudio, - SendChatAction, SendContact, SendLocation, SendMediaGroup, SendMessage, - SendPhoto, SendPoll, SendVenue, SendVideoNote, SendVoice, - SetChatDescription, StopMessageLiveLocation, UnbanChatMember, + AnswerCallbackQuery, AnswerPreCheckoutQuery, AnswerShippingQuery, + DeleteChatStickerSet, EditMessageLiveLocation, ForwardMessage, + GetChatMember, GetChatMembersCount, GetFile, GetMe, GetUpdates, + KickChatMember, PinChatMessage, PromoteChatMember, RestrictChatMember, + SendAnimation, SendAudio, SendChatAction, SendContact, SendDocument, + SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, + SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, + SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, diff --git a/src/bot/download.rs b/src/bot/download.rs index 331de593..dd2d5566 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -3,10 +3,9 @@ use tokio::io::AsyncWrite; #[cfg(feature = "unstable-stream")] use ::{bytes::Bytes, tokio::stream::Stream}; -use crate::bot::Bot; #[cfg(feature = "unstable-stream")] use crate::network::download_file_stream; -use crate::{network::download_file, DownloadError}; +use crate::{bot::Bot, network::download_file, DownloadError}; impl Bot { /// Download file from telegram into `destination`. diff --git a/src/dispatcher/handler.rs b/src/dispatcher/handler.rs index 6a456a8e..9ce74580 100644 --- a/src/dispatcher/handler.rs +++ b/src/dispatcher/handler.rs @@ -1,5 +1,4 @@ -use std::future::Future; -use std::pin::Pin; +use std::{future::Future, pin::Pin}; use futures::FutureExt; diff --git a/src/dispatcher/simple/error_policy.rs b/src/dispatcher/simple/error_policy.rs index 676d561f..8e922c63 100644 --- a/src/dispatcher/simple/error_policy.rs +++ b/src/dispatcher/simple/error_policy.rs @@ -1,6 +1,4 @@ -use std::fmt::Debug; -use std::future::Future; -use std::pin::Pin; +use std::{fmt::Debug, future::Future, pin::Pin}; // TODO: shouldn't it be trait? pub enum ErrorPolicy<'a, E> { diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 23fa47ab..34fca780 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -267,8 +267,10 @@ where #[cfg(test)] mod tests { - use std::convert::Infallible; - use std::sync::atomic::{AtomicI32, Ordering}; + use std::{ + convert::Infallible, + sync::atomic::{AtomicI32, Ordering}, + }; use futures::Stream; @@ -352,8 +354,7 @@ mod tests { fn one_message_updater( ) -> StreamUpdater<impl Stream<Item = Result<Update, Infallible>>> { - use futures::future::ready; - use futures::stream; + use futures::{future::ready, stream}; StreamUpdater::new(stream::once(ready(Ok(message_update())))) } diff --git a/src/dispatcher/updater.rs b/src/dispatcher/updater.rs index 7b0017fb..47d131ec 100644 --- a/src/dispatcher/updater.rs +++ b/src/dispatcher/updater.rs @@ -7,8 +7,7 @@ use futures::{stream, Stream, StreamExt}; use pin_project::pin_project; -use crate::bot::Bot; -use crate::{types::Update, RequestError}; +use crate::{bot::Bot, types::Update, RequestError}; // Currently just a placeholder, but I'll add here some methods /// Updater is stream of updates. diff --git a/src/requests/answer_callback_query.rs b/src/requests/answer_callback_query.rs index 600cb755..9d62af18 100644 --- a/src/requests/answer_callback_query.rs +++ b/src/requests/answer_callback_query.rs @@ -1,7 +1,9 @@ -use crate::bot::Bot; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::True; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::True, +}; use async_trait::async_trait; /// Use this method to send answers to callback queries sent from inline diff --git a/src/requests/answer_pre_checkout_query.rs b/src/requests/answer_pre_checkout_query.rs index 9087cab4..e4842ef9 100644 --- a/src/requests/answer_pre_checkout_query.rs +++ b/src/requests/answer_pre_checkout_query.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::True, diff --git a/src/requests/answer_shipping_query.rs b/src/requests/answer_shipping_query.rs index 4ba8fcd2..90b59fa9 100644 --- a/src/requests/answer_shipping_query.rs +++ b/src/requests/answer_shipping_query.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ShippingOption, True}, diff --git a/src/requests/delete_chat_sticker_set.rs b/src/requests/delete_chat_sticker_set.rs index abb64fb6..2d1c849c 100644 --- a/src/requests/delete_chat_sticker_set.rs +++ b/src/requests/delete_chat_sticker_set.rs @@ -1,7 +1,9 @@ -use crate::bot::Bot; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, True}; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, True}, +}; use async_trait::async_trait; /// Use this method to delete a group sticker set from a supergroup. The bot diff --git a/src/requests/edit_message_live_location.rs b/src/requests/edit_message_live_location.rs index b8d820b1..8ac0e77a 100644 --- a/src/requests/edit_message_live_location.rs +++ b/src/requests/edit_message_live_location.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, diff --git a/src/requests/form_builder.rs b/src/requests/form_builder.rs index 01698d5c..66cbb913 100644 --- a/src/requests/form_builder.rs +++ b/src/requests/form_builder.rs @@ -2,10 +2,9 @@ use std::path::PathBuf; use reqwest::multipart::Form; -use crate::types::InputFile; use crate::{ requests::utils, - types::{ChatId, InputMedia, ParseMode}, + types::{ChatId, InputFile, InputMedia, ParseMode}, }; /// This is a convenient struct that builds `reqwest::multipart::Form` diff --git a/src/requests/forward_message.rs b/src/requests/forward_message.rs index 5cce7880..b99166b0 100644 --- a/src/requests/forward_message.rs +++ b/src/requests/forward_message.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message}, diff --git a/src/requests/get_chat.rs b/src/requests/get_chat.rs index 0853de27..c8fb74a8 100644 --- a/src/requests/get_chat.rs +++ b/src/requests/get_chat.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{Chat, ChatId}, diff --git a/src/requests/get_chat_member.rs b/src/requests/get_chat_member.rs index 293db180..ce3eae65 100644 --- a/src/requests/get_chat_member.rs +++ b/src/requests/get_chat_member.rs @@ -1,7 +1,9 @@ -use crate::bot::Bot; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, ChatMember}; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, ChatMember}, +}; use async_trait::async_trait; /// Use this method to get information about a member of a chat. Returns a diff --git a/src/requests/get_chat_members_count.rs b/src/requests/get_chat_members_count.rs index 3595cf49..ae224c59 100644 --- a/src/requests/get_chat_members_count.rs +++ b/src/requests/get_chat_members_count.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{Chat, ChatId}, diff --git a/src/requests/get_file.rs b/src/requests/get_file.rs index 263705ac..43cb809d 100644 --- a/src/requests/get_file.rs +++ b/src/requests/get_file.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::File, diff --git a/src/requests/get_me.rs b/src/requests/get_me.rs index 4b1ad322..29d5a546 100644 --- a/src/requests/get_me.rs +++ b/src/requests/get_me.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::User, diff --git a/src/requests/get_updates.rs b/src/requests/get_updates.rs index bc773bf3..8e25a784 100644 --- a/src/requests/get_updates.rs +++ b/src/requests/get_updates.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::Update, diff --git a/src/requests/get_user_profile_photos.rs b/src/requests/get_user_profile_photos.rs index 16c57eb2..88ccaf5a 100644 --- a/src/requests/get_user_profile_photos.rs +++ b/src/requests/get_user_profile_photos.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::UserProfilePhotos, diff --git a/src/requests/kick_chat_member.rs b/src/requests/kick_chat_member.rs index c00690d3..cdbef073 100644 --- a/src/requests/kick_chat_member.rs +++ b/src/requests/kick_chat_member.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, True}, diff --git a/src/requests/pin_chat_message.rs b/src/requests/pin_chat_message.rs index d93f47bc..c8567e36 100644 --- a/src/requests/pin_chat_message.rs +++ b/src/requests/pin_chat_message.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, True}, diff --git a/src/requests/promote_chat_member.rs b/src/requests/promote_chat_member.rs index f37676fb..2c416233 100644 --- a/src/requests/promote_chat_member.rs +++ b/src/requests/promote_chat_member.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, True}, diff --git a/src/requests/restrict_chat_member.rs b/src/requests/restrict_chat_member.rs index 51dead83..f17b5ba6 100644 --- a/src/requests/restrict_chat_member.rs +++ b/src/requests/restrict_chat_member.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, ChatPermissions, True}, diff --git a/src/requests/send_animation.rs b/src/requests/send_animation.rs index 279eafff..0bfa8a3e 100644 --- a/src/requests/send_animation.rs +++ b/src/requests/send_animation.rs @@ -1,9 +1,11 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, +}; ///Use this method to send animation files (GIF or H.264/MPEG-4 AVC video /// without sound). On success, the sent Message is returned. Bots can currently diff --git a/src/requests/send_audio.rs b/src/requests/send_audio.rs index 4b4411ef..95d29b61 100644 --- a/src/requests/send_audio.rs +++ b/src/requests/send_audio.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{form_builder::FormBuilder, Request, ResponseResult}, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, diff --git a/src/requests/send_chat_action.rs b/src/requests/send_chat_action.rs index 403b88ba..af4db368 100644 --- a/src/requests/send_chat_action.rs +++ b/src/requests/send_chat_action.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatAction, ChatId, True}, diff --git a/src/requests/send_contact.rs b/src/requests/send_contact.rs index f4465f48..56e64cf9 100644 --- a/src/requests/send_contact.rs +++ b/src/requests/send_contact.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, diff --git a/src/requests/send_document.rs b/src/requests/send_document.rs index 5c4af3af..9224955c 100644 --- a/src/requests/send_document.rs +++ b/src/requests/send_document.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, diff --git a/src/requests/send_location.rs b/src/requests/send_location.rs index 5df4edf3..bd76e9a2 100644 --- a/src/requests/send_location.rs +++ b/src/requests/send_location.rs @@ -2,8 +2,8 @@ use serde::Serialize; use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, diff --git a/src/requests/send_media_group.rs b/src/requests/send_media_group.rs index f9e0995a..ea503ed8 100644 --- a/src/requests/send_media_group.rs +++ b/src/requests/send_media_group.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network::request_multipart, requests::{form_builder::FormBuilder, Request, ResponseResult}, types::{ChatId, InputFile, InputMedia, Message}, diff --git a/src/requests/send_message.rs b/src/requests/send_message.rs index 371b640d..cd16ca21 100644 --- a/src/requests/send_message.rs +++ b/src/requests/send_message.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message, ParseMode, ReplyMarkup}, diff --git a/src/requests/send_photo.rs b/src/requests/send_photo.rs index 63a78666..76c1b18b 100644 --- a/src/requests/send_photo.rs +++ b/src/requests/send_photo.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{form_builder::FormBuilder, Request, ResponseResult}, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, diff --git a/src/requests/send_poll.rs b/src/requests/send_poll.rs index 4322f6e6..d5d2e2da 100644 --- a/src/requests/send_poll.rs +++ b/src/requests/send_poll.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, diff --git a/src/requests/send_venue.rs b/src/requests/send_venue.rs index 02eebeca..30e501c8 100644 --- a/src/requests/send_venue.rs +++ b/src/requests/send_venue.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, Message, ReplyMarkup}, diff --git a/src/requests/send_video.rs b/src/requests/send_video.rs index 85b5d27a..4763fde1 100644 --- a/src/requests/send_video.rs +++ b/src/requests/send_video.rs @@ -1,9 +1,11 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, +}; ///Use this method to send video files, Telegram clients support mp4 videos /// (other formats may be sent as Document). On success, the sent Message is diff --git a/src/requests/send_video_note.rs b/src/requests/send_video_note.rs index c506058a..70e6c9df 100644 --- a/src/requests/send_video_note.rs +++ b/src/requests/send_video_note.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, InputFile, Message, ReplyMarkup}, diff --git a/src/requests/send_voice.rs b/src/requests/send_voice.rs index 9f152d02..af3724b9 100644 --- a/src/requests/send_voice.rs +++ b/src/requests/send_voice.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, InputFile, Message, ParseMode, ReplyMarkup}, diff --git a/src/requests/set_chat_sticker_set.rs b/src/requests/set_chat_sticker_set.rs index 14927d0d..f27d82d5 100644 --- a/src/requests/set_chat_sticker_set.rs +++ b/src/requests/set_chat_sticker_set.rs @@ -1,7 +1,9 @@ -use crate::bot::Bot; -use crate::network; -use crate::requests::{Request, ResponseResult}; -use crate::types::{ChatId, True}; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, True}, +}; use async_trait::async_trait; /// Use this method to set a new group sticker set for a supergroup. The bot diff --git a/src/requests/stop_message_live_location.rs b/src/requests/stop_message_live_location.rs index 541690c2..7ded4251 100644 --- a/src/requests/stop_message_live_location.rs +++ b/src/requests/stop_message_live_location.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, InlineKeyboardMarkup, Message}, diff --git a/src/requests/unban_chat_member.rs b/src/requests/unban_chat_member.rs index 9a2f266c..2af14c12 100644 --- a/src/requests/unban_chat_member.rs +++ b/src/requests/unban_chat_member.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::ChatId, diff --git a/src/requests/unpin_chat_message.rs b/src/requests/unpin_chat_message.rs index aabf57dc..1e7f9ef6 100644 --- a/src/requests/unpin_chat_message.rs +++ b/src/requests/unpin_chat_message.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; -use crate::bot::Bot; use crate::{ + bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, True}, diff --git a/src/types/inline_query_result.rs b/src/types/inline_query_result.rs index f4644b79..098d0dc4 100644 --- a/src/types/inline_query_result.rs +++ b/src/types/inline_query_result.rs @@ -49,9 +49,8 @@ pub enum InlineQueryResult { #[cfg(test)] mod tests { - use crate::types::inline_keyboard_markup::InlineKeyboardMarkup; - use crate::types::parse_mode::ParseMode; use crate::types::{ + inline_keyboard_markup::InlineKeyboardMarkup, parse_mode::ParseMode, InlineQueryResult, InlineQueryResultCachedAudio, InputMessageContent, }; diff --git a/src/types/message.rs b/src/types/message.rs index 188d3bdb..61bebed0 100644 --- a/src/types/message.rs +++ b/src/types/message.rs @@ -190,7 +190,6 @@ pub enum MediaKind { mod getters { use std::ops::Deref; - use crate::types::message::MessageKind::{Pinned, SupergroupChatCreated}; use crate::types::{ self, message::{ @@ -203,7 +202,7 @@ mod getters { ChannelChatCreated, Common, ConnectedWebsite, DeleteChatPhoto, GroupChatCreated, Invoice, LeftChatMember, Migrate, NewChatMembers, NewChatPhoto, NewChatTitle, PassportData, - SuccessfulPayment, + Pinned, SuccessfulPayment, SupergroupChatCreated, }, }, Chat, ForwardedFrom, Message, MessageEntity, PhotoSize, Sender, True, diff --git a/src/types/unit_true.rs b/src/types/unit_true.rs index 0efe1b33..a953dcb2 100644 --- a/src/types/unit_true.rs +++ b/src/types/unit_true.rs @@ -1,5 +1,7 @@ -use serde::de::{self, Deserialize, Deserializer, Visitor}; -use serde::ser::{Serialize, Serializer}; +use serde::{ + de::{self, Deserialize, Deserializer, Visitor}, + ser::{Serialize, Serializer}, +}; #[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] pub struct True; From 351229a6c012b853a8b430aea92e182b7b934d58 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Thu, 17 Oct 2019 19:48:48 +0300 Subject: [PATCH 27/66] added method setChatTitle --- src/bot/api.rs | 14 +++++- src/requests/mod.rs | 2 + src/requests/set_chat_title.rs | 86 ++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/requests/set_chat_title.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index 924e7abc..a52fa3f6 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -9,7 +9,7 @@ use crate::{ SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, - UnpinChatMessage, + UnpinChatMessage, SetChatTitle }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -356,4 +356,16 @@ impl Bot { { SendAnimation::new(self, chat_id, animation) } + + pub fn set_chat_title<C, T>( + &self, + chat_id: C, + title: T, + ) -> SetChatTitle + where + C: Into<ChatId>, + T: Into<String>, + { + SetChatTitle::new(self, chat_id, title) + } } diff --git a/src/requests/mod.rs b/src/requests/mod.rs index d2ee64f9..496d71ef 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -36,6 +36,7 @@ pub use send_video_note::*; pub use send_voice::*; pub use set_chat_description::*; pub use set_chat_sticker_set::*; +pub use set_chat_title::*; pub use stop_message_live_location::*; pub use unban_chat_member::*; pub use unpin_chat_message::*; @@ -76,6 +77,7 @@ mod send_video_note; mod send_voice; mod set_chat_description; mod set_chat_sticker_set; +mod set_chat_title; mod stop_message_live_location; mod unban_chat_member; mod unpin_chat_message; diff --git a/src/requests/set_chat_title.rs b/src/requests/set_chat_title.rs new file mode 100644 index 00000000..bdf21dc9 --- /dev/null +++ b/src/requests/set_chat_title.rs @@ -0,0 +1,86 @@ +use async_trait::async_trait; + +use crate::bot::Bot; +use crate::types::{ChatId, True}; +use crate::requests::{Request, ResponseResult}; +use crate::network; + +#[derive(Debug, Clone, Serialize)] +pub struct SetChatTitle<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + chat_id: ChatId, + title: String, +} + +#[async_trait] +impl Request for SetChatTitle<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl SetChatTitle<'_> { + async fn send(self) -> ResponseResult<True> { + network::request_json( + &self.bot.client(), + &self.bot.token(), + "SetChatTitle", + &self + ).await + } +} + +impl<'a> SetChatTitle<'a> { + pub(crate) fn new<C, T>( + bot: &'a Bot, + chat_id: C, + title: T + ) -> Self + where + C: Into<ChatId>, + T: Into<String>, + { + Self { + bot, + chat_id: chat_id.into(), + title: title.into(), + } + } + + pub fn chat_id<C>(mut self, chat_id: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = chat_id.into(); + self + } + + pub fn title<C>(mut self, title: C) -> Self + where + C: Into<String>, + { + self.title = title.into(); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize() { + let bot = Bot::new("token"); + let chat_id = 123; + let title = "title"; + let method = SetChatTitle::new(&bot, chat_id, title); + + let expected = r#"{"chat_id":123,"title":"title"}"#; + let actual = serde_json::to_string::<SetChatTitle>(&method).unwrap(); + assert_eq!(actual, expected); + } +} From 495e62e9aa7d3604f17b08188e0a0ef187e7d538 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Fri, 18 Oct 2019 03:20:28 +0600 Subject: [PATCH 28/66] Improve bot/mod.rs --- src/bot/mod.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/bot/mod.rs b/src/bot/mod.rs index d4e6d884..6c7dbcc2 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -11,28 +11,35 @@ pub struct Bot { client: Client, } -/// Constructors impl Bot { - pub fn new(token: &str) -> Self { + pub fn new<S>(token: S) -> Self + where + S: Into<String>, + { Bot { - token: String::from(token), + token: token.into(), client: Client::new(), } } - pub fn with_client(token: &str, client: Client) -> Self { + pub fn with_client<S>(token: S, client: Client) -> Self + where + S: Into<String>, + { Bot { - token: String::from(token), + token: token.into(), client, } } } impl Bot { + #[inline] pub fn token(&self) -> &str { &self.token } + #[inline] pub fn client(&self) -> &Client { &self.client } From 6f4bd193827c8639d634e608419a33a6688c634d Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Fri, 18 Oct 2019 03:36:13 +0600 Subject: [PATCH 29/66] Import bot::Bot into lib.rs --- src/bot/api.rs | 11 +++-------- src/bot/download.rs | 2 +- src/bot/mod.rs | 3 +-- src/dispatcher/simple/mod.rs | 2 +- src/lib.rs | 3 ++- src/requests/mod.rs | 2 +- src/requests/set_chat_title.rs | 35 +++++++++++++++++----------------- src/types/mod.rs | 2 +- 8 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index a52fa3f6..5725aefc 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -8,13 +8,12 @@ use crate::{ SendAnimation, SendAudio, SendChatAction, SendContact, SendDocument, SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, - SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, - UnpinChatMessage, SetChatTitle + SetChatStickerSet, SetChatTitle, StopMessageLiveLocation, + UnbanChatMember, UnpinChatMessage, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; -/// Telegram functions impl Bot { pub fn get_me(&self) -> GetMe { GetMe::new(self) @@ -357,11 +356,7 @@ impl Bot { SendAnimation::new(self, chat_id, animation) } - pub fn set_chat_title<C, T>( - &self, - chat_id: C, - title: T, - ) -> SetChatTitle + pub fn set_chat_title<C, T>(&self, chat_id: C, title: T) -> SetChatTitle where C: Into<ChatId>, T: Into<String>, diff --git a/src/bot/download.rs b/src/bot/download.rs index dd2d5566..b768f43d 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -19,7 +19,7 @@ impl Bot { /// use telebofr::types::File as TgFile; /// use tokio::fs::File; /// # use telebofr::RequestError; - /// use telebofr::bot::Bot; + /// use telebofr::Bot; /// /// # async fn run() -> Result<(), Box<dyn std::error::Error>> { /// let bot = Bot::new("TOKEN"); diff --git a/src/bot/mod.rs b/src/bot/mod.rs index 6c7dbcc2..f2b45f51 100644 --- a/src/bot/mod.rs +++ b/src/bot/mod.rs @@ -1,10 +1,9 @@ -//! A Telegram bot. - use reqwest::Client; mod api; mod download; +/// A Telegram bot used to build requests. #[derive(Debug, Clone)] pub struct Bot { token: String, diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 34fca780..5c7048f5 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -32,7 +32,7 @@ type Handlers<'a, T, E> = /// /// Simplest example: /// ```no_run -/// # use telebofr::bot::Bot; +/// # use telebofr::Bot; /// use telebofr::types::Message; /// async fn run() { /// use std::convert::Infallible; diff --git a/src/lib.rs b/src/lib.rs index 8d244ff6..533071c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,12 +5,13 @@ extern crate serde; #[macro_use] extern crate thiserror; +pub use bot::Bot; pub use errors::{DownloadError, RequestError}; mod errors; mod network; -pub mod bot; +mod bot; pub mod dispatcher; pub mod requests; pub mod types; diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 496d71ef..32ea3cae 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -1,4 +1,4 @@ -//! Raw API functions. +//! API requests. use async_trait::async_trait; use serde::de::DeserializeOwned; diff --git a/src/requests/set_chat_title.rs b/src/requests/set_chat_title.rs index bdf21dc9..85553fc5 100644 --- a/src/requests/set_chat_title.rs +++ b/src/requests/set_chat_title.rs @@ -1,9 +1,11 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::types::{ChatId, True}; -use crate::requests::{Request, ResponseResult}; -use crate::network; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, True}, +}; #[derive(Debug, Clone, Serialize)] pub struct SetChatTitle<'a> { @@ -29,20 +31,17 @@ impl SetChatTitle<'_> { &self.bot.client(), &self.bot.token(), "SetChatTitle", - &self - ).await + &self, + ) + .await } } impl<'a> SetChatTitle<'a> { - pub(crate) fn new<C, T>( - bot: &'a Bot, - chat_id: C, - title: T - ) -> Self - where - C: Into<ChatId>, - T: Into<String>, + pub(crate) fn new<C, T>(bot: &'a Bot, chat_id: C, title: T) -> Self + where + C: Into<ChatId>, + T: Into<String>, { Self { bot, @@ -52,16 +51,16 @@ impl<'a> SetChatTitle<'a> { } pub fn chat_id<C>(mut self, chat_id: C) -> Self - where - C: Into<ChatId>, + where + C: Into<ChatId>, { self.chat_id = chat_id.into(); self } pub fn title<C>(mut self, title: C) -> Self - where - C: Into<String>, + where + C: Into<String>, { self.title = title.into(); self diff --git a/src/types/mod.rs b/src/types/mod.rs index 62dbe9b9..e1f08e4f 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,4 +1,4 @@ -//! Raw API structures. +//! API types. pub use animation::*; pub use audio::*; From 2a3d7cfbfb54da5d94f9aafef7d09f12637fe448 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 17:00:14 +0300 Subject: [PATCH 30/66] added method deleteChatPhoto --- src/bot/api.rs | 12 +++++- src/requests/delete_chat_photo.rs | 70 +++++++++++++++++++++++++++++++ src/requests/mod.rs | 2 + 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 src/requests/delete_chat_photo.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index a52fa3f6..37087c7b 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -9,7 +9,7 @@ use crate::{ SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, - UnpinChatMessage, SetChatTitle + UnpinChatMessage, SetChatTitle, DeleteChatPhoto }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -368,4 +368,14 @@ impl Bot { { SetChatTitle::new(self, chat_id, title) } + + pub fn delete_chat_photo<C>( + &self, + chat_id: C, + ) -> DeleteChatPhoto + where + C: Into<ChatId>, + { + DeleteChatPhoto::new(self, chat_id) + } } diff --git a/src/requests/delete_chat_photo.rs b/src/requests/delete_chat_photo.rs new file mode 100644 index 00000000..340f61cb --- /dev/null +++ b/src/requests/delete_chat_photo.rs @@ -0,0 +1,70 @@ +use async_trait::async_trait; + +use crate::bot::Bot; +use crate::types::{ChatId, True}; +use crate::requests::{ResponseResult, Request}; +use crate::network; + +#[derive(Debug, Clone, Serialize)] +pub struct DeleteChatPhoto<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + chat_id: ChatId +} + +#[async_trait] +impl Request for DeleteChatPhoto<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl DeleteChatPhoto<'_> { + async fn send(self) -> ResponseResult<True> { + network::request_json( + self.bot.client(), + self.bot.token(), + "deleteChatPhoto", + &self + ).await + } +} + +impl<'a> DeleteChatPhoto<'a> { + pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self + where + C: Into<ChatId> + { + Self { + bot, + chat_id: chat_id.into(), + } + } + + pub fn chat_id<C>(mut self, chat_id: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = chat_id.into(); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize() { + let bot = Bot::new("token"); + let chat_id = 123; + let method = DeleteChatPhoto::new(&bot, chat_id); + + let expected = r#"{"chat_id":123}"#; + let actual = serde_json::to_string::<DeleteChatPhoto>(&method).unwrap(); + assert_eq!(actual, expected); + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 496d71ef..afce883d 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -6,6 +6,7 @@ use serde::de::DeserializeOwned; pub use answer_callback_query::*; pub use answer_pre_checkout_query::*; pub use answer_shipping_query::*; +pub use delete_chat_photo::*; pub use delete_chat_sticker_set::*; pub use edit_message_live_location::*; pub use forward_message::*; @@ -47,6 +48,7 @@ mod utils; mod answer_callback_query; mod answer_pre_checkout_query; mod answer_shipping_query; +mod delete_chat_photo; mod delete_chat_sticker_set; mod edit_message_live_location; mod forward_message; From 85a81dbe52e4e3b75b1f356a76e3d0df9e9fb65e Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 17:00:45 +0300 Subject: [PATCH 31/66] fix wrong method_name --- src/requests/set_chat_title.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requests/set_chat_title.rs b/src/requests/set_chat_title.rs index bdf21dc9..494e9acc 100644 --- a/src/requests/set_chat_title.rs +++ b/src/requests/set_chat_title.rs @@ -28,7 +28,7 @@ impl SetChatTitle<'_> { network::request_json( &self.bot.client(), &self.bot.token(), - "SetChatTitle", + "setChatTitle", &self ).await } From e760c281b8f290c40e4f129d0290b85841720724 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 17:15:27 +0300 Subject: [PATCH 32/66] added method setChatPhoto --- src/bot/api.rs | 14 +++++- src/requests/mod.rs | 2 + src/requests/set_chat_photo.rs | 91 ++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/requests/set_chat_photo.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index 37087c7b..4301e89d 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -9,7 +9,7 @@ use crate::{ SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, - UnpinChatMessage, SetChatTitle, DeleteChatPhoto + UnpinChatMessage, SetChatTitle, DeleteChatPhoto, SetChatPhoto }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -378,4 +378,16 @@ impl Bot { { DeleteChatPhoto::new(self, chat_id) } + + pub fn set_chat_photo<C, P>( + &self, + chat_id: C, + photo: P, + ) -> SetChatPhoto + where + C: Into<ChatId>, + P: Into<InputFile>, + { + SetChatPhoto::new(self, chat_id, photo) + } } diff --git a/src/requests/mod.rs b/src/requests/mod.rs index afce883d..b626aa9a 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -36,6 +36,7 @@ pub use send_video::*; pub use send_video_note::*; pub use send_voice::*; pub use set_chat_description::*; +pub use set_chat_photo::*; pub use set_chat_sticker_set::*; pub use set_chat_title::*; pub use stop_message_live_location::*; @@ -78,6 +79,7 @@ mod send_video; mod send_video_note; mod send_voice; mod set_chat_description; +mod set_chat_photo; mod set_chat_sticker_set; mod set_chat_title; mod stop_message_live_location; diff --git a/src/requests/set_chat_photo.rs b/src/requests/set_chat_photo.rs new file mode 100644 index 00000000..34236fed --- /dev/null +++ b/src/requests/set_chat_photo.rs @@ -0,0 +1,91 @@ +use async_trait::async_trait; + +use crate::bot::Bot; +use crate::types::{ChatId, True, InputFile}; +use crate::requests::{Request, ResponseResult}; +use crate::network; +use crate::requests::form_builder::FormBuilder; + +#[derive(Debug, Clone, Serialize)] +pub struct SetChatPhoto<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + chat_id: ChatId, + photo: InputFile, +} + +#[async_trait] +impl Request for SetChatPhoto<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl SetChatPhoto<'_> { + async fn send(self) -> ResponseResult<True> { + let params = FormBuilder::new() + .add("chat_id", self.chat_id) + .add("photo", self.photo); + + network::request_multipart( + self.bot.client(), + self.bot.token(), + "setChatPhoto", + params.build(), + ).await + } +} + +impl<'a> SetChatPhoto<'a> { + pub(crate) fn new<C, P>( + bot: &'a Bot, + chat_id: C, + photo: P + ) -> Self + where + C: Into<ChatId>, + P: Into<InputFile>, + { + Self { + bot, + chat_id: chat_id.into(), + photo: photo.into(), + } + } + + pub fn chat_id<C>(mut self, chat_id: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = chat_id.into(); + self + } + + pub fn photo<P>(mut self, photo: P) -> Self + where + P: Into<InputFile>, + { + self.photo = photo.into(); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize() { + let bot = Bot::new("token"); + let chat_id = 123; + let photo_url = "https://some_url".to_string(); + let method = SetChatPhoto::new(&bot, chat_id, InputFile::Url(photo_url)); + + let expected = r#"{"chat_id":123,"photo":"https://some_url"}"#; + let actual = serde_json::to_string::<SetChatPhoto>(&method).unwrap(); + assert_eq!(actual, expected); + } +} From 2cb5adeebe4cd508a4a9d4a7b06de2b2c7d580e8 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 18:17:07 +0300 Subject: [PATCH 33/66] added method exportChatInviteLink --- src/bot/api.rs | 13 ++++- src/requests/export_chat_invite_link.rs | 70 +++++++++++++++++++++++++ src/requests/mod.rs | 2 + 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/requests/export_chat_invite_link.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index 4301e89d..cc12f9c2 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -9,7 +9,8 @@ use crate::{ SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, - UnpinChatMessage, SetChatTitle, DeleteChatPhoto, SetChatPhoto + UnpinChatMessage, SetChatTitle, DeleteChatPhoto, SetChatPhoto, + ExportCharInviteLink }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -390,4 +391,14 @@ impl Bot { { SetChatPhoto::new(self, chat_id, photo) } + + pub fn export_chat_invite_link<C>( + &self, + chat_id: C, + ) -> ExportCharInviteLink + where + C: Into<ChatId>, + { + ExportCharInviteLink::new(self, chat_id) + } } diff --git a/src/requests/export_chat_invite_link.rs b/src/requests/export_chat_invite_link.rs new file mode 100644 index 00000000..ef3140cf --- /dev/null +++ b/src/requests/export_chat_invite_link.rs @@ -0,0 +1,70 @@ +use async_trait::async_trait; + +use crate::bot::Bot; +use crate::types::ChatId; +use crate::requests::{ResponseResult, Request}; +use crate::network; + +#[derive(Debug, Clone, Serialize)] +pub struct ExportCharInviteLink<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + chat_id: ChatId +} + +#[async_trait] +impl Request for ExportCharInviteLink<'_> { + type Output = String; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl ExportCharInviteLink<'_> { + async fn send(self) -> ResponseResult<String> { + network::request_json( + self.bot.client(), + self.bot.token(), + "exportChatInviteLink", + &self + ).await + } +} + +impl<'a> ExportCharInviteLink<'a> { + pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self + where + C: Into<ChatId> + { + Self { + bot, + chat_id: chat_id.into(), + } + } + + pub fn chat_id<C>(mut self, chat_id: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = chat_id.into(); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize() { + let bot = Bot::new("token"); + let chat_id = 123; + let method = ExportCharInviteLink::new(&bot, chat_id); + + let expected = r#"{"chat_id":123}"#; + let actual = serde_json::to_string::<ExportCharInviteLink>(&method).unwrap(); + assert_eq!(actual, expected); + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index b626aa9a..cc8e8e65 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -9,6 +9,7 @@ pub use answer_shipping_query::*; pub use delete_chat_photo::*; pub use delete_chat_sticker_set::*; pub use edit_message_live_location::*; +pub use export_chat_invite_link::*; pub use forward_message::*; pub use get_chat::*; pub use get_chat_member::*; @@ -52,6 +53,7 @@ mod answer_shipping_query; mod delete_chat_photo; mod delete_chat_sticker_set; mod edit_message_live_location; +mod export_chat_invite_link; mod forward_message; mod get_chat; mod get_chat_member; From 6467f0397805430fd667d39f1cedca896b947488 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 18:43:52 +0300 Subject: [PATCH 34/66] added skip_serializing_if to Option<> fields --- src/types/chat_permissions.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/types/chat_permissions.rs b/src/types/chat_permissions.rs index 08a5b908..869398aa 100644 --- a/src/types/chat_permissions.rs +++ b/src/types/chat_permissions.rs @@ -1,11 +1,19 @@ #[derive(Debug, Deserialize, Hash, PartialEq, Eq, Serialize, Clone)] pub struct ChatPermissions { + #[serde(skip_serializing_if = "Option::is_none")] pub can_send_messages: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_send_media_messages: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_send_polls: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_send_other_messages: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_add_web_page_previews: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_change_info: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_invite_users: Option<bool>, + #[serde(skip_serializing_if = "Option::is_none")] pub can_pin_messages: Option<bool>, } From 363259e4164f932468c8c387e50091d022ba23ab Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 18:44:16 +0300 Subject: [PATCH 35/66] added method setChatPermissions --- src/bot/api.rs | 14 +++- src/requests/mod.rs | 2 + src/requests/set_chat_permissions.rs | 95 ++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/requests/set_chat_permissions.rs diff --git a/src/bot/api.rs b/src/bot/api.rs index cc12f9c2..1d743a15 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -10,7 +10,7 @@ use crate::{ SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, SetChatTitle, DeleteChatPhoto, SetChatPhoto, - ExportCharInviteLink + ExportCharInviteLink, SetChatPermissions }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -401,4 +401,16 @@ impl Bot { { ExportCharInviteLink::new(self, chat_id) } + + pub fn set_chat_permissions<C, CP>( + &self, + chat_id: C, + permissions: CP, + ) -> SetChatPermissions + where + C: Into<ChatId>, + CP: Into<ChatPermissions>, + { + SetChatPermissions::new(self, chat_id, permissions) + } } diff --git a/src/requests/mod.rs b/src/requests/mod.rs index cc8e8e65..013d3707 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -37,6 +37,7 @@ pub use send_video::*; pub use send_video_note::*; pub use send_voice::*; pub use set_chat_description::*; +pub use set_chat_permissions::*; pub use set_chat_photo::*; pub use set_chat_sticker_set::*; pub use set_chat_title::*; @@ -81,6 +82,7 @@ mod send_video; mod send_video_note; mod send_voice; mod set_chat_description; +mod set_chat_permissions; mod set_chat_photo; mod set_chat_sticker_set; mod set_chat_title; diff --git a/src/requests/set_chat_permissions.rs b/src/requests/set_chat_permissions.rs new file mode 100644 index 00000000..fe5d3c52 --- /dev/null +++ b/src/requests/set_chat_permissions.rs @@ -0,0 +1,95 @@ +use async_trait::async_trait; + +use crate::bot::Bot; +use crate::types::{ChatId, ChatPermissions, True}; +use crate::requests::{ResponseResult, Request}; +use crate::network; + +#[derive(Debug, Clone, Serialize)] +pub struct SetChatPermissions<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + chat_id: ChatId, + permissions: ChatPermissions +} + +#[async_trait] +impl Request for SetChatPermissions<'_> { + type Output = True; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl SetChatPermissions<'_> { + async fn send(self) -> ResponseResult<True> { + network::request_json( + self.bot.client(), + self.bot.token(), + "setChatPermissions", + &self + ).await + } +} + +impl<'a> SetChatPermissions<'a> { + pub(crate) fn new<C, CP>( + bot: &'a Bot, + chat_id: C, + permissions: CP, + ) -> Self + where + C: Into<ChatId>, + CP: Into<ChatPermissions>, + { + Self { + bot, + chat_id: chat_id.into(), + permissions: permissions.into(), + } + } + + pub fn chat_id<C>(mut self, chat_id: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = chat_id.into(); + self + } + + pub fn permissions<CP>(mut self, permissions: CP) -> Self + where + CP: Into<ChatPermissions> + { + self.permissions = permissions.into(); + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn serialize() { + let bot = Bot::new("token"); + let chat_id = 123; + let permissions = ChatPermissions { + can_send_messages: Some(true), + can_send_media_messages: None, + can_send_polls: None, + can_send_other_messages: None, + can_add_web_page_previews: None, + can_change_info: None, + can_invite_users: None, + can_pin_messages: None + }; + let method = SetChatPermissions::new(&bot, chat_id, permissions); + + let expected = r#"{"chat_id":123,"permissions":{"can_send_messages":true}}"#; + let actual = serde_json::to_string::<SetChatPermissions>(&method).unwrap(); + assert_eq!(actual, expected); + } +} From 4a0e601063ed5eeb94921c7fb70ab54202c57280 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 20:01:22 +0300 Subject: [PATCH 36/66] added type False --- src/types/mod.rs | 2 ++ src/types/unit_false.rs | 78 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/types/unit_false.rs diff --git a/src/types/mod.rs b/src/types/mod.rs index e1f08e4f..eadb5942 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -47,6 +47,7 @@ pub use sticker::*; pub use sticker_set::*; pub use successful_payment::*; pub use unit_true::*; +pub use unit_false::*; pub use update::*; pub use user::*; pub use user_profile_photos::*; @@ -130,6 +131,7 @@ mod shipping_query; mod sticker; mod sticker_set; mod successful_payment; +mod unit_false; mod unit_true; mod update; mod user; diff --git a/src/types/unit_false.rs b/src/types/unit_false.rs new file mode 100644 index 00000000..2ac0f793 --- /dev/null +++ b/src/types/unit_false.rs @@ -0,0 +1,78 @@ +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::de::Visitor; + +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub struct False; + +impl std::convert::TryFrom<bool> for False { + type Error = (); + + fn try_from(value: bool) -> Result<Self, Self::Error> { + #[allow(clippy::match_bool)] + match value { + true => Err(()), + false => Ok(False), + } + } +} + +impl<'de> Deserialize<'de> for False { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de> + { + deserializer.deserialize_bool(FalseVisitor) + } +} + +struct FalseVisitor; + +impl<'de> Visitor<'de> for FalseVisitor { + type Value = False; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "bool, equal to `false`") + } + + fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + #[allow(clippy::match_bool)] + match value { + true => Err(E::custom("expected `false`, found `true`")), + false => Ok(False) + } + } +} + +impl Serialize for False { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer + { + serializer.serialize_bool(false) + } +} + +#[cfg(test)] +mod tests { + use serde_json::{from_str, to_string}; + + use super::False; + + #[test] + fn unit_true_de() { + let json = "false"; + let expected = False; + let actual = from_str(json).unwrap(); + assert_eq!(expected, actual); + } + + #[test] + fn unit_true_se() { + let actual = to_string(&False).unwrap(); + let expected = "false"; + assert_eq!(expected, actual); + } +} From 1e0f60bdef67a9896509445053c0a44cae87ca25 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 20:02:27 +0300 Subject: [PATCH 37/66] added True and False types --- src/network/telegram_response.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/telegram_response.rs b/src/network/telegram_response.rs index 05e7acb7..a3c77b4e 100644 --- a/src/network/telegram_response.rs +++ b/src/network/telegram_response.rs @@ -2,6 +2,7 @@ use reqwest::StatusCode; use crate::{ requests::ResponseResult, types::ResponseParameters, RequestError, + types::{True, False} }; #[derive(Deserialize)] @@ -10,14 +11,14 @@ pub enum TelegramResponse<R> { Ok { /// A dummy field. Used only for deserialization. #[allow(dead_code)] - ok: bool, // TODO: True type + ok: True, result: R, }, Err { /// A dummy field. Used only for deserialization. #[allow(dead_code)] - ok: bool, // TODO: False type + ok: False, description: String, error_code: u16, From 281d01d1a27bc790409d7dcb4c83ceebf53d0ad1 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 20:08:09 +0300 Subject: [PATCH 38/66] tests were renamed --- src/types/unit_false.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/unit_false.rs b/src/types/unit_false.rs index 2ac0f793..78299be1 100644 --- a/src/types/unit_false.rs +++ b/src/types/unit_false.rs @@ -62,7 +62,7 @@ mod tests { use super::False; #[test] - fn unit_true_de() { + fn unit_false_de() { let json = "false"; let expected = False; let actual = from_str(json).unwrap(); @@ -70,7 +70,7 @@ mod tests { } #[test] - fn unit_true_se() { + fn unit_false_se() { let actual = to_string(&False).unwrap(); let expected = "false"; assert_eq!(expected, actual); From e7ef38c1b2d6728b38e5e532abef91408a11276d Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 20:48:02 +0300 Subject: [PATCH 39/66] added handle_message function --- src/dispatcher/simple/mod.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 5c7048f5..d9301228 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -227,16 +227,16 @@ where match kind { UpdateKind::Message(mes) => { - call!(self.message_handlers, mes) + self.handle_message(mes, &self.message_handlers).await; } UpdateKind::EditedMessage(mes) => { - call!(self.edited_message_handlers, mes) + self.handle_message(mes, &self.edited_message_handlers).await; } UpdateKind::ChannelPost(post) => { - call!(self.channel_post_handlers, post) + self.handle_message(post, &self.channel_post_handlers).await; } UpdateKind::EditedChannelPost(post) => { - call!(self.edited_channel_post_handlers, post) + self.handle_message(post, &self.edited_channel_post_handlers).await; } UpdateKind::InlineQuery(query) => { call!(self.inline_query_handlers, query) @@ -252,6 +252,27 @@ where }) .await; } + + async fn handle_message(&self, message: Message, handlers: &Handlers<'a, Message, E>) { + let handler = handlers.iter().find_map(|e|{ + let (filter, handler) = e; + if filter.test(&message) { + Some(handler) + } else { + None + } + }); + match handler { + Some(handler) => { + if let Err(err) = handler.handle(message).await { + self.error_policy.handle_error(err).await + } + } + None => { + log::warn!("unhandled update {:?}", message); + } + } + } } #[async_trait(? Send)] From 69096dc01dc24f867e4e4ed1054c04762c495387 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 21:06:36 +0300 Subject: [PATCH 40/66] Revert "added handle_message function" This reverts commit e7ef38c1 --- src/dispatcher/simple/mod.rs | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index d9301228..5c7048f5 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -227,16 +227,16 @@ where match kind { UpdateKind::Message(mes) => { - self.handle_message(mes, &self.message_handlers).await; + call!(self.message_handlers, mes) } UpdateKind::EditedMessage(mes) => { - self.handle_message(mes, &self.edited_message_handlers).await; + call!(self.edited_message_handlers, mes) } UpdateKind::ChannelPost(post) => { - self.handle_message(post, &self.channel_post_handlers).await; + call!(self.channel_post_handlers, post) } UpdateKind::EditedChannelPost(post) => { - self.handle_message(post, &self.edited_channel_post_handlers).await; + call!(self.edited_channel_post_handlers, post) } UpdateKind::InlineQuery(query) => { call!(self.inline_query_handlers, query) @@ -252,27 +252,6 @@ where }) .await; } - - async fn handle_message(&self, message: Message, handlers: &Handlers<'a, Message, E>) { - let handler = handlers.iter().find_map(|e|{ - let (filter, handler) = e; - if filter.test(&message) { - Some(handler) - } else { - None - } - }); - match handler { - Some(handler) => { - if let Err(err) = handler.handle(message).await { - self.error_policy.handle_error(err).await - } - } - None => { - log::warn!("unhandled update {:?}", message); - } - } - } } #[async_trait(? Send)] From c85dc0fb6869672ed83e815746103e9ec3ef1ed4 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Sat, 19 Oct 2019 21:11:36 +0300 Subject: [PATCH 41/66] added handle_message function --- src/dispatcher/simple/mod.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 5c7048f5..d9301228 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -227,16 +227,16 @@ where match kind { UpdateKind::Message(mes) => { - call!(self.message_handlers, mes) + self.handle_message(mes, &self.message_handlers).await; } UpdateKind::EditedMessage(mes) => { - call!(self.edited_message_handlers, mes) + self.handle_message(mes, &self.edited_message_handlers).await; } UpdateKind::ChannelPost(post) => { - call!(self.channel_post_handlers, post) + self.handle_message(post, &self.channel_post_handlers).await; } UpdateKind::EditedChannelPost(post) => { - call!(self.edited_channel_post_handlers, post) + self.handle_message(post, &self.edited_channel_post_handlers).await; } UpdateKind::InlineQuery(query) => { call!(self.inline_query_handlers, query) @@ -252,6 +252,27 @@ where }) .await; } + + async fn handle_message(&self, message: Message, handlers: &Handlers<'a, Message, E>) { + let handler = handlers.iter().find_map(|e|{ + let (filter, handler) = e; + if filter.test(&message) { + Some(handler) + } else { + None + } + }); + match handler { + Some(handler) => { + if let Err(err) = handler.handle(message).await { + self.error_policy.handle_error(err).await + } + } + None => { + log::warn!("unhandled update {:?}", message); + } + } + } } #[async_trait(? Send)] From e0a278701d297ee280044f89afa9268339e16c2a Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 01:33:45 +0600 Subject: [PATCH 42/66] Remove the unnecessary comment (bot/api.rs) --- src/bot/api.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index 0e56cc24..ff529396 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -15,7 +15,6 @@ use crate::{ types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; -/// Telegram functions impl Bot { pub fn get_me(&self) -> GetMe { GetMe::new(self) From 66147232e6411fffe73f2c3b5c980403c23cc594 Mon Sep 17 00:00:00 2001 From: RustemB <bakirov.com@ya.ru> Date: Sun, 20 Oct 2019 12:30:07 +0500 Subject: [PATCH 43/66] levaeChat --- src/requests/leave_chat.rs | 50 ++++++++++++++++++++++++++++++++++++++ src/requests/mod.rs | 2 ++ 2 files changed, 52 insertions(+) create mode 100644 src/requests/leave_chat.rs diff --git a/src/requests/leave_chat.rs b/src/requests/leave_chat.rs new file mode 100644 index 00000000..2433dec2 --- /dev/null +++ b/src/requests/leave_chat.rs @@ -0,0 +1,50 @@ +use async_trait::async_trait; + +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::ChatId, +}; + +/// Use this method for your bot to leave a group, supergroup or channel. +/// Returns True on success. +#[derive(Debug, Clone, Serialize)] +pub struct LeaveChat<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + /// Unique identifier for the target chat or username + /// of the target supergroup or channel (in the format @channelusername) + chat_id: ChatId, +} + +#[async_trait] +impl Request for LeaveChat<'_> { + type Output = bool; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl LeaveChat<'_> { + pub async fn send(self) -> ResponseResult<bool> { + network::request_json( + self.bot.client(), + self.bot.token(), + "leaveChat", + &self, + ) + .await + } +} + +impl<'a> LeaveChat<'a> { + pub fn chat_id<C>(mut self, value: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = value.into(); + self + } +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 3ed8a93d..e356bb2f 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -19,6 +19,7 @@ pub use get_me::*; pub use get_updates::*; pub use get_user_profile_photos::*; pub use kick_chat_member::*; +pub use leave_chat::*; pub use pin_chat_message::*; pub use promote_chat_member::*; pub use restrict_chat_member::*; @@ -64,6 +65,7 @@ mod get_me; mod get_updates; mod get_user_profile_photos; mod kick_chat_member; +mod leave_chat; mod pin_chat_message; mod promote_chat_member; mod restrict_chat_member; From 5916460ca1c15b5b5317cfa0abddd522c772cfda Mon Sep 17 00:00:00 2001 From: RustemB <bakirov.com@ya.ru> Date: Sun, 20 Oct 2019 15:40:28 +0500 Subject: [PATCH 44/66] +getChatAdministrators --- src/requests/get_chat_administrators.rs | 60 +++++++++++++++++++++++++ src/requests/mod.rs | 2 + 2 files changed, 62 insertions(+) create mode 100644 src/requests/get_chat_administrators.rs diff --git a/src/requests/get_chat_administrators.rs b/src/requests/get_chat_administrators.rs new file mode 100644 index 00000000..693a2c70 --- /dev/null +++ b/src/requests/get_chat_administrators.rs @@ -0,0 +1,60 @@ +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, ChatMember}, +}; +use async_trait::async_trait; + +/// Use this method to get a list of administrators in a chat. On success, returns an Array of ChatMember objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned +#[derive(Debug, Clone, Serialize)] +pub struct GetChatAdministrators<'a> { + #[serde(skip_serializing)] + bot: &'a Bot, + + /// Unique identifier for the target chat or username of the target + /// supergroup or channel (in the format @channelusername) + chat_id: ChatId, +} + +#[async_trait] +impl Request for GetChatAdministrators<'_> { + type Output = Vec<ChatMember>; + + async fn send_boxed(self) -> ResponseResult<Self::Output> { + self.send().await + } +} + +impl GetChatAdministrators<'_> { + async fn send(&self) -> ResponseResult<Vec<ChatMember>> { + network::request_json( + self.bot.client(), + self.bot.token(), + "getChatAdministrators", + &self, + ) + .await + } +} + +impl<'a> GetChatAdministrators<'a> { + pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self + where + C: Into<ChatId>, + { + Self { + bot, + chat_id: chat_id.into(), + } + } + + pub fn chat_id<C>(mut self, value: C) -> Self + where + C: Into<ChatId>, + { + self.chat_id = value.into(); + self + } + +} diff --git a/src/requests/mod.rs b/src/requests/mod.rs index e356bb2f..5349630b 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -12,6 +12,7 @@ pub use edit_message_live_location::*; pub use export_chat_invite_link::*; pub use forward_message::*; pub use get_chat::*; +pub use get_chat_administrators::*; pub use get_chat_member::*; pub use get_chat_members_count::*; pub use get_file::*; @@ -58,6 +59,7 @@ mod edit_message_live_location; mod export_chat_invite_link; mod forward_message; mod get_chat; +mod get_chat_administrators; mod get_chat_member; mod get_chat_members_count; mod get_file; From 0a1d032e144eac69f76e24245cebac04dac6893a Mon Sep 17 00:00:00 2001 From: RustemB <bakirov.com@ya.ru> Date: Sun, 20 Oct 2019 16:01:32 +0500 Subject: [PATCH 45/66] api.rs changed --- src/bot/api.rs | 27 ++++++++++++++++++++++++++- src/requests/get_chat.rs | 10 ++++++++++ src/requests/leave_chat.rs | 9 +++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index ff529396..936331d0 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -10,7 +10,8 @@ use crate::{ SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, UnpinChatMessage, SetChatTitle, DeleteChatPhoto, SetChatPhoto, - ExportCharInviteLink, SetChatPermissions + ExportCharInviteLink, SetChatPermissions, LeaveChat, GetChatAdministrators, + GetChat, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -119,6 +120,13 @@ impl Bot { AnswerPreCheckoutQuery::new(self, pre_checkout_query_id, ok) } + pub fn get_chat<I>(&self, chat_id: I) -> GetChat + where + I: Into<ChatId>, + { + GetChat::new(self, chat_id) + } + pub fn answer_shipping_query<I, O>( &self, shipping_query_id: I, @@ -322,6 +330,13 @@ impl Bot { GetChatMember::new(self, chat_id, user_id) } + pub fn get_chat_administrators<C, I>(&self, chat_id: C) -> GetChatAdministrators + where + C: Into<ChatId>, + { + GetChatAdministrators::new(self, chat_id) + } + pub fn get_chat_members_count<C>(&self, chat_id: C) -> GetChatMembersCount where C: Into<ChatId>, @@ -375,6 +390,16 @@ impl Bot { DeleteChatPhoto::new(self, chat_id) } + pub fn leave_chat<C>( + &self, + chat_id: C, + ) -> LeaveChat + where + C: Into<ChatId>, + { + LeaveChat::new(self, chat_id) + } + pub fn set_chat_photo<C, P>( &self, chat_id: C, diff --git a/src/requests/get_chat.rs b/src/requests/get_chat.rs index c8fb74a8..aa8e3ca4 100644 --- a/src/requests/get_chat.rs +++ b/src/requests/get_chat.rs @@ -42,6 +42,16 @@ impl GetChat<'_> { } impl<'a> GetChat<'a> { + pub(crate) fn new<F>(bot: &'a Bot, value: F) -> Self + where + F: Into<ChatId>, + { + Self { + bot, + chat_id: value.into(), + } + } + pub fn chat_id<C>(mut self, value: C) -> Self where C: Into<ChatId>, diff --git a/src/requests/leave_chat.rs b/src/requests/leave_chat.rs index 2433dec2..88ad3fd6 100644 --- a/src/requests/leave_chat.rs +++ b/src/requests/leave_chat.rs @@ -40,6 +40,15 @@ impl LeaveChat<'_> { } impl<'a> LeaveChat<'a> { + pub(crate) fn new<F>(bot: &'a Bot, value: F) -> Self + where + F: Into<ChatId>, + { + Self { + bot, + chat_id: value.into(), + } + } pub fn chat_id<C>(mut self, value: C) -> Self where C: Into<ChatId>, From e80d4d5a62106a133574bd99db318d445b531df1 Mon Sep 17 00:00:00 2001 From: RustemB <bakirov.com@ya.ru> Date: Sun, 20 Oct 2019 16:05:20 +0500 Subject: [PATCH 46/66] some cahnges --- src/requests/get_chat.rs | 8 ++++---- src/requests/leave_chat.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/requests/get_chat.rs b/src/requests/get_chat.rs index aa8e3ca4..6a8bc711 100644 --- a/src/requests/get_chat.rs +++ b/src/requests/get_chat.rs @@ -42,21 +42,21 @@ impl GetChat<'_> { } impl<'a> GetChat<'a> { - pub(crate) fn new<F>(bot: &'a Bot, value: F) -> Self + pub(crate) fn new<F>(bot: &'a Bot, chat_id: F) -> Self where F: Into<ChatId>, { Self { bot, - chat_id: value.into(), + chat_id: chat_id.into(), } } - pub fn chat_id<C>(mut self, value: C) -> Self + pub fn chat_id<C>(mut self, chat_id: C) -> Self where C: Into<ChatId>, { - self.chat_id = value.into(); + self.chat_id = chat_id.into(); self } } diff --git a/src/requests/leave_chat.rs b/src/requests/leave_chat.rs index 88ad3fd6..1f52a1f6 100644 --- a/src/requests/leave_chat.rs +++ b/src/requests/leave_chat.rs @@ -40,20 +40,20 @@ impl LeaveChat<'_> { } impl<'a> LeaveChat<'a> { - pub(crate) fn new<F>(bot: &'a Bot, value: F) -> Self + pub(crate) fn new<F>(bot: &'a Bot, chat_id: F) -> Self where F: Into<ChatId>, { Self { bot, - chat_id: value.into(), + chat_id: chat_id.into(), } } - pub fn chat_id<C>(mut self, value: C) -> Self + pub fn chat_id<C>(mut self, chat_id: C) -> Self where C: Into<ChatId>, { - self.chat_id = value.into(); + self.chat_id = chat_id.into(); self } } From 1a87e726773f938d54576cf13b5e7857dfeee1b3 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 17:14:12 +0600 Subject: [PATCH 47/66] Fmt --- src/bot/api.rs | 44 ++++++++++--------------- src/requests/delete_chat_photo.rs | 19 ++++++----- src/requests/export_chat_invite_link.rs | 22 ++++++++----- src/requests/get_chat_administrators.rs | 7 ++-- src/requests/set_chat_permissions.rs | 33 ++++++++++--------- src/requests/set_chat_photo.rs | 23 +++++++------ src/requests/set_chat_title.rs | 12 +++---- 7 files changed, 78 insertions(+), 82 deletions(-) diff --git a/src/bot/api.rs b/src/bot/api.rs index 936331d0..7a43b6c1 100644 --- a/src/bot/api.rs +++ b/src/bot/api.rs @@ -2,16 +2,16 @@ use crate::{ bot::Bot, requests::{ AnswerCallbackQuery, AnswerPreCheckoutQuery, AnswerShippingQuery, - DeleteChatStickerSet, EditMessageLiveLocation, ForwardMessage, + DeleteChatPhoto, DeleteChatStickerSet, EditMessageLiveLocation, + ExportCharInviteLink, ForwardMessage, GetChat, GetChatAdministrators, GetChatMember, GetChatMembersCount, GetFile, GetMe, GetUpdates, - KickChatMember, PinChatMessage, PromoteChatMember, RestrictChatMember, - SendAnimation, SendAudio, SendChatAction, SendContact, SendDocument, - SendLocation, SendMediaGroup, SendMessage, SendPhoto, SendPoll, - SendVenue, SendVideo, SendVideoNote, SendVoice, SetChatDescription, - SetChatStickerSet, StopMessageLiveLocation, UnbanChatMember, - UnpinChatMessage, SetChatTitle, DeleteChatPhoto, SetChatPhoto, - ExportCharInviteLink, SetChatPermissions, LeaveChat, GetChatAdministrators, - GetChat, + KickChatMember, LeaveChat, PinChatMessage, PromoteChatMember, + RestrictChatMember, SendAnimation, SendAudio, SendChatAction, + SendContact, SendDocument, SendLocation, SendMediaGroup, SendMessage, + SendPhoto, SendPoll, SendVenue, SendVideo, SendVideoNote, SendVoice, + SetChatDescription, SetChatPermissions, SetChatPhoto, + SetChatStickerSet, SetChatTitle, StopMessageLiveLocation, + UnbanChatMember, UnpinChatMessage, }, types::{ChatAction, ChatId, ChatPermissions, InputFile, InputMedia}, }; @@ -330,7 +330,10 @@ impl Bot { GetChatMember::new(self, chat_id, user_id) } - pub fn get_chat_administrators<C, I>(&self, chat_id: C) -> GetChatAdministrators + pub fn get_chat_administrators<C, I>( + &self, + chat_id: C, + ) -> GetChatAdministrators where C: Into<ChatId>, { @@ -380,31 +383,21 @@ impl Bot { SetChatTitle::new(self, chat_id, title) } - pub fn delete_chat_photo<C>( - &self, - chat_id: C, - ) -> DeleteChatPhoto + pub fn delete_chat_photo<C>(&self, chat_id: C) -> DeleteChatPhoto where C: Into<ChatId>, { DeleteChatPhoto::new(self, chat_id) } - pub fn leave_chat<C>( - &self, - chat_id: C, - ) -> LeaveChat + pub fn leave_chat<C>(&self, chat_id: C) -> LeaveChat where C: Into<ChatId>, { LeaveChat::new(self, chat_id) } - pub fn set_chat_photo<C, P>( - &self, - chat_id: C, - photo: P, - ) -> SetChatPhoto + pub fn set_chat_photo<C, P>(&self, chat_id: C, photo: P) -> SetChatPhoto where C: Into<ChatId>, P: Into<InputFile>, @@ -412,10 +405,7 @@ impl Bot { SetChatPhoto::new(self, chat_id, photo) } - pub fn export_chat_invite_link<C>( - &self, - chat_id: C, - ) -> ExportCharInviteLink + pub fn export_chat_invite_link<C>(&self, chat_id: C) -> ExportCharInviteLink where C: Into<ChatId>, { diff --git a/src/requests/delete_chat_photo.rs b/src/requests/delete_chat_photo.rs index 340f61cb..f674d4f9 100644 --- a/src/requests/delete_chat_photo.rs +++ b/src/requests/delete_chat_photo.rs @@ -1,16 +1,18 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::types::{ChatId, True}; -use crate::requests::{ResponseResult, Request}; -use crate::network; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, True}, +}; #[derive(Debug, Clone, Serialize)] pub struct DeleteChatPhoto<'a> { #[serde(skip_serializing)] bot: &'a Bot, - chat_id: ChatId + chat_id: ChatId, } #[async_trait] @@ -28,15 +30,16 @@ impl DeleteChatPhoto<'_> { self.bot.client(), self.bot.token(), "deleteChatPhoto", - &self - ).await + &self, + ) + .await } } impl<'a> DeleteChatPhoto<'a> { pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self where - C: Into<ChatId> + C: Into<ChatId>, { Self { bot, diff --git a/src/requests/export_chat_invite_link.rs b/src/requests/export_chat_invite_link.rs index ef3140cf..dfb809b0 100644 --- a/src/requests/export_chat_invite_link.rs +++ b/src/requests/export_chat_invite_link.rs @@ -1,16 +1,18 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::types::ChatId; -use crate::requests::{ResponseResult, Request}; -use crate::network; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::ChatId, +}; #[derive(Debug, Clone, Serialize)] pub struct ExportCharInviteLink<'a> { #[serde(skip_serializing)] bot: &'a Bot, - chat_id: ChatId + chat_id: ChatId, } #[async_trait] @@ -28,15 +30,16 @@ impl ExportCharInviteLink<'_> { self.bot.client(), self.bot.token(), "exportChatInviteLink", - &self - ).await + &self, + ) + .await } } impl<'a> ExportCharInviteLink<'a> { pub(crate) fn new<C>(bot: &'a Bot, chat_id: C) -> Self where - C: Into<ChatId> + C: Into<ChatId>, { Self { bot, @@ -64,7 +67,8 @@ mod tests { let method = ExportCharInviteLink::new(&bot, chat_id); let expected = r#"{"chat_id":123}"#; - let actual = serde_json::to_string::<ExportCharInviteLink>(&method).unwrap(); + let actual = + serde_json::to_string::<ExportCharInviteLink>(&method).unwrap(); assert_eq!(actual, expected); } } diff --git a/src/requests/get_chat_administrators.rs b/src/requests/get_chat_administrators.rs index 693a2c70..f80c63c9 100644 --- a/src/requests/get_chat_administrators.rs +++ b/src/requests/get_chat_administrators.rs @@ -6,7 +6,11 @@ use crate::{ }; use async_trait::async_trait; -/// Use this method to get a list of administrators in a chat. On success, returns an Array of ChatMember objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned +/// Use this method to get a list of administrators in a chat. On success, +/// returns an Array of ChatMember objects that contains information about all +/// chat administrators except other bots. If the chat is a group or a +/// supergroup and no administrators were appointed, only the creator will be +/// returned #[derive(Debug, Clone, Serialize)] pub struct GetChatAdministrators<'a> { #[serde(skip_serializing)] @@ -56,5 +60,4 @@ impl<'a> GetChatAdministrators<'a> { self.chat_id = value.into(); self } - } diff --git a/src/requests/set_chat_permissions.rs b/src/requests/set_chat_permissions.rs index fe5d3c52..a7307935 100644 --- a/src/requests/set_chat_permissions.rs +++ b/src/requests/set_chat_permissions.rs @@ -1,9 +1,11 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::types::{ChatId, ChatPermissions, True}; -use crate::requests::{ResponseResult, Request}; -use crate::network; +use crate::{ + bot::Bot, + network, + requests::{Request, ResponseResult}, + types::{ChatId, ChatPermissions, True}, +}; #[derive(Debug, Clone, Serialize)] pub struct SetChatPermissions<'a> { @@ -11,7 +13,7 @@ pub struct SetChatPermissions<'a> { bot: &'a Bot, chat_id: ChatId, - permissions: ChatPermissions + permissions: ChatPermissions, } #[async_trait] @@ -29,17 +31,14 @@ impl SetChatPermissions<'_> { self.bot.client(), self.bot.token(), "setChatPermissions", - &self - ).await + &self, + ) + .await } } impl<'a> SetChatPermissions<'a> { - pub(crate) fn new<C, CP>( - bot: &'a Bot, - chat_id: C, - permissions: CP, - ) -> Self + pub(crate) fn new<C, CP>(bot: &'a Bot, chat_id: C, permissions: CP) -> Self where C: Into<ChatId>, CP: Into<ChatPermissions>, @@ -61,7 +60,7 @@ impl<'a> SetChatPermissions<'a> { pub fn permissions<CP>(mut self, permissions: CP) -> Self where - CP: Into<ChatPermissions> + CP: Into<ChatPermissions>, { self.permissions = permissions.into(); self @@ -84,12 +83,14 @@ mod tests { can_add_web_page_previews: None, can_change_info: None, can_invite_users: None, - can_pin_messages: None + can_pin_messages: None, }; let method = SetChatPermissions::new(&bot, chat_id, permissions); - let expected = r#"{"chat_id":123,"permissions":{"can_send_messages":true}}"#; - let actual = serde_json::to_string::<SetChatPermissions>(&method).unwrap(); + let expected = + r#"{"chat_id":123,"permissions":{"can_send_messages":true}}"#; + let actual = + serde_json::to_string::<SetChatPermissions>(&method).unwrap(); assert_eq!(actual, expected); } } diff --git a/src/requests/set_chat_photo.rs b/src/requests/set_chat_photo.rs index 34236fed..6a372d1a 100644 --- a/src/requests/set_chat_photo.rs +++ b/src/requests/set_chat_photo.rs @@ -1,10 +1,11 @@ use async_trait::async_trait; -use crate::bot::Bot; -use crate::types::{ChatId, True, InputFile}; -use crate::requests::{Request, ResponseResult}; -use crate::network; -use crate::requests::form_builder::FormBuilder; +use crate::{ + bot::Bot, + network, + requests::{form_builder::FormBuilder, Request, ResponseResult}, + types::{ChatId, InputFile, True}, +}; #[derive(Debug, Clone, Serialize)] pub struct SetChatPhoto<'a> { @@ -35,16 +36,13 @@ impl SetChatPhoto<'_> { self.bot.token(), "setChatPhoto", params.build(), - ).await + ) + .await } } impl<'a> SetChatPhoto<'a> { - pub(crate) fn new<C, P>( - bot: &'a Bot, - chat_id: C, - photo: P - ) -> Self + pub(crate) fn new<C, P>(bot: &'a Bot, chat_id: C, photo: P) -> Self where C: Into<ChatId>, P: Into<InputFile>, @@ -82,7 +80,8 @@ mod tests { let bot = Bot::new("token"); let chat_id = 123; let photo_url = "https://some_url".to_string(); - let method = SetChatPhoto::new(&bot, chat_id, InputFile::Url(photo_url)); + let method = + SetChatPhoto::new(&bot, chat_id, InputFile::Url(photo_url)); let expected = r#"{"chat_id":123,"photo":"https://some_url"}"#; let actual = serde_json::to_string::<SetChatPhoto>(&method).unwrap(); diff --git a/src/requests/set_chat_title.rs b/src/requests/set_chat_title.rs index adb94576..a86f8e2b 100644 --- a/src/requests/set_chat_title.rs +++ b/src/requests/set_chat_title.rs @@ -38,14 +38,10 @@ impl SetChatTitle<'_> { } impl<'a> SetChatTitle<'a> { - pub(crate) fn new<C, T>( - bot: &'a Bot, - chat_id: C, - title: T - ) -> Self - where - C: Into<ChatId>, - T: Into<String>, + pub(crate) fn new<C, T>(bot: &'a Bot, chat_id: C, title: T) -> Self + where + C: Into<ChatId>, + T: Into<String>, { Self { bot, From e1b3ba2227b4dfd13efcdde53cc4211346757950 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 22:45:22 +0600 Subject: [PATCH 48/66] Remove PartialOrd, Ord for True, False --- hw.doc | Bin 0 -> 33280 bytes src/dispatcher/simple/mod.rs | 29 +++++++++++++++++++++++------ src/network/telegram_response.rs | 5 +++-- src/types/mod.rs | 2 +- src/types/unit_false.rs | 16 +++++++++------- src/types/unit_true.rs | 2 +- 6 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 hw.doc diff --git a/hw.doc b/hw.doc new file mode 100644 index 0000000000000000000000000000000000000000..0bdb82bf7864fcf9f8101fb143c11cc9a5ea15fb GIT binary patch literal 33280 zcmeI54{%l0oyX68?<TxJ0!avnNZ}D9QmQe3N%)hHKNw<!0HR{M6&nNug@6!S>vkMa zTAi+S(RHoU>1?$_9k+EH?7wl^Zbi0bo&KT7w$yeVSKF@B-ErK&XuEbQ+3)9^ck}Lh zyhmOXEtYqa?|b*2`#b0S&hOtj_uO;uJN&b<mmYa?>dPi=TVSH*#88nb45fS8Zw-!1 zjfrTVv=c)^LqW23^V|DK0&gXFMTad?Vu66p#|SZ@NEj=O6N-frVZ1OwkO`PFp<I|K zR0xzaS>NXfQ-pJcsls`}G~olnbYX@N7iJ2T!udj#aDgyOxKNlad{CGpd`P%RxLBwb zE)i;kTA@y;7aD{{VXn|5Gz;^D`N9HWp#XniQDR@aXZ3c4*{Z(*>Ecq;ukY>VlafsC z+hkcxSb(|YME<$Z<w}#UKPiD+WEPfx5Wh+Dl{xT#j`4rK^V?sq1UzXtssK+53ybK{ zjoEKMO&9Td*{18aZ{4wV!$5rX*6r&qUcB|DTeht4AFzGGvQ?xl-g>?53D~dJfjwW{ zY+j%D^_yKmr}~urxk^t(bc%B)6iK`cMPS!2efmqs-(0@2^lSIU%!e-g#;@ovo)WNY z&UXvg{0f2oZlged_bGus?{0y9?*W0n?_q)d?{NX9|NAZ1myxz=<F>w=;_dzGwy(DV zls=9;y<4|$>DyerZtK7n+wW0d{oH!frf>6~4{q(ym)+m@v)jjX9ro=0?ZpSblGy*~ zcUQmMeAh2vH{+JA{qPt0#ZQ0n#p?4)|Kam$|3z;;u~=yZX=&x=BWkN>{>Jv`u8Ixn z+K&xIjJ`D%=vDu)-E1*^X0wjz<7=zDIaOX$mDgD1)mM4#RqA~^=9uL@F|$(W?3rS= zbf4?*5H9bIm=#Lv@AhK@!W!-O>HKxwp0AR<Qgqj=GK-{*^{Qi?*`$8x1{1eE`($y} zHp`5iWyW=R!B=6GH&K;LQzezEq|%=o^ZImnimlR|m~njQm>p>pnbrDhR;{<FRkh|e zJC0x!0*&WYT5i&57-s}DWm#w#hXgb;v(PY33217w&@he(Xxg*TFwO~RR%W4L92C&> zWual56wut9g@$odK(i|YO<kG{@5@3Hmf<5=Xu>jlG7C*uhR<Z73Cr-gEHq&mzMO?7 zEW=}2Xu>k|A}8Aq@^Lb(wl-E4VFa6MhxG{=7R!x_<VHniO^>gUE;czc3qA6Leyr%n zihf*zzBUUzvW31_^u?ktPSCe!p-0Zpmx#VZ^d$)&S(%}Y4QV#emxU&512<=(3ERM~ zEHq&oxGxJ$*ajZSLKC)uC$rFmZQz+KG+`TfE(=ZA242n}^Tv!ekceFw%7i{FPcM41 z?LiZkXIU1SusmmGp$W^gHVaKyp6yv^!tz|1g(fV|zAQB1xO8&{8hk3u^R6s3VV>{H zLKEiskt{S}o}bJ@<9MEL{rZ_GSEiH9bidti@mu{m`#H~#n{L0&Z}u1a9onz)YyBp_ z#_tkDuB%vL!gEosW+$7)>NPj0-@HY=Ggomdw7*@r!G3Pjm?mzz)Pr+v$2QkoReB`) za+LOzn9FSXdeQc)9P%%<{qIdWTdY1kvQ1;6A=5g?>sGBtqQ|0)naWM2-{{X5*YH>8 zUvBwsS4y*v&(Tqh_8BWI?-{SyF<!lOx#GtJb^Xd~OY(edwa~1x*PQTogFSAHc^{2= zb+(OVK9*aS=&9F=!|lVPgH^gt-D1|NWt+_oQ88<9jaoL-XZ9ebtJy7v*7xb`CQDIh zG)}lS=6%FmU3z?|*8hm;CYh`4*-heNy~ZB#Q%WQ*iIi;HxKkOobPt&wf+W+guL0pY zVUFdy-Dk#PoR#GcmAq73!2M>GkH7ko1*0D%y3%L#Q!1&|`1P`Z1=bE)B|m7x(wr_S z))>jhjj4Q%sm}EWggzxpW({Vw+STV{@e@+y%C-H;(r}V?9N&Bjj?n=ek4v;}*C}X; zB4OJ5PC*Nwj`kuewMYDmlv12gYV|gTIk~l3>L-0>BC}D$$0TWM?6!^71K-jJG$}24 z!-*N5IpTMTW=z_s6Q5XWChi?H6?<<r8fa<`Yk5zpY`D~pI9K!(ND_sz<7uYNbZGQ? z#BWnMMdnKB_g3pc9kR)Fb`~XOmYHZ(w67}4c(o#Ryjo$T-AhWJ^M4~vBMCeYYvJ0W z*Gi^LbyTX3<F<}5rc-vbO%$7~Kf~*C@p`M}wOG8CtClHP`I??GJIa=|&$6wJ6yOyF z*1FeOPB~g($c0qPG`BWGHI)~jgTi5{;BnNm(v%#GnaHK(e^=#2lyZ@Yi@GvFO?+Vv zDWJY0je3RUp{{`ItkMk8t|J^xL=%zqPLuW~$k%r6RHI5$MOUh*jt)Btu%YpiJ^r;> z^~WV67wgvB$VOx+(0SU)-1UhW?FCm9U^yizxl*q^@ZGDVIj^tEBWEFAClAA8J+rm| zk5zP3t()~n+xt~>U;(u8YE!;$P}eRK_bLj4jFHe;;`Rb8u~<4!UT4KM_qkf_S!?G% zOSK=AH^r;iJH;zbF==A6XYME<Hjf{+qfC7P^Rd^MHM<W-uH9|S#{|dW!)A+>P>n6= z{sOL)$IDabNw#E>Ys7q5RBTb9RG1{p6sm*^1Z3_uW)~v9+fPmPGo}_~OfAfqIwp}C z)OGTAHvTMS%<>b%s!a?^6SD=z*mc|W<MB@^NE<C-0^y#?#vF+o^Mk77+&As#+{Y#w z^V+$_JgCX;e-a)Qo)Eq*d|x;y91@NSFAA>+uL*w;d<pQN%2e_1cn)22^n-4^Q8+k7 z<rS$Bw3E3FS`FB5Gt-ZuKb=Mz$RhSfR64;#2CEC%iwz<Vh$&=(i4N{B;M*UZtu)UR z4N^d`c{_)OK*Wr-`6yZBmi~MCu1us`lTe}8d*cRoD}ATnnO$b~=7_nz24r`_Le z_dl((#@uB;pH`8+S>lySH9KjC+2#Gme;qS-dR0@$o2R`}@x0&r$8Y@7JfpLoIpE#6 zbhi1iw?b+;>XG4>_H)RKNn?xD;)r=V8aD)x%3}!Y@2xHDiRzTO&+gxE_i6J(N(<T$ zRof6uRBiZ}c0X-Je3$Ape=+{TGPVwuCgaHaK*r%V*l>{6hUojO4K{eCwZVU%wZVqk zv^EsH58Ch<`C{O&HoB_~|8B+&646ig*Qe#Wrz?7>f|H_0m>Z%g(c>@24KgTC#AD6L z+Pk|uB%3+f-R05S-AO1Lj;T6`{n)0s*y%;+E_9hTNM=s72;5$66WWCip;LHE?K~ma z?o`D6iro{Hq30Z99#$a(Z6Y%C3B8(iXX5=5Q9L9HcZNv&rWoQ(u|AS#h!1zG6wZ{X z6HT7M>$;V~nG34IXRzfpO5w~;)QKhYU?D%8so|n(zENj<MSsTu+WK38Gpog0@{DI& zu4FSbA^p!uC3MGAZB1<IG}r8Q1F=a53n)Xqtt};>a6Ps=%2NkYIqece=HZQDp2jdX zX{e1atd=bj40K3XVNKtyfLJnlPkJdXN80C=x_)C!y~D&cq+D-4p>OWObBCp0w2dk! z*}k;Qp~LVDi0&!P%B}WxJBQ-#<!n+-URkKfEW2Epy4jb$;j7QMuF>3l%m(EesZGcx z7vYRl&SizUmBY2vfB=_B6<K$h9&@=(AsFRa(o&VOQSE1LjJdXt+wz!SW1el3N?M*H zPh8LS>q`0-Tf&ExH?H}CP3C%)1E*YrQXaDUiM~hLMv~Q%iri#1QaOwK+{)p~`xYw` z>>{vjbp<)fCtLmnsy`QhSS{%>ix}KN<l4V6$GoY&G%rVM#RG0otC@GWN^>h(ZIokM zPtLh&mZThnmQ$!cn=d*mr^Cf6oqu1Jqvl4o@eW;Vd9lywy6A^e#YPVXe|3G`UDxcr zZA|>yx*KeQ`LMnY=w^7-uJZEDoqN>trlpd?_HR*RFBx4<mzMt=y#&f@MxSS-9BJMr zJ;ltQ-x?`b;x_t-WJ!XZ$z9E>l!uPkEmrK_sQJ!5bCZe7uKVTL+vRJYlzsJT=5tjV zeg5$6NZ{44c;2!&1KYv!r(FTgqBNvu9!mFa`nGQF>u=6rXGQ*G)7YD=wIwk`N~X9y z<^tJ<h9=l`qRghS&m0%S5BAfyyKO>SqQu}kohp1BS0S2I&v|PQ{WMXp(Dyx|TwR(X zdP(wlr`!1|C(V;`Dsq;V4y{$jyW?(!Qmx9dGmAOpP7<w>cwbK*zT>?YB&Sd4@+8*{ zojsf@@w-U3L>Gpv#)?XgOzgcRzS`c!`bH}HJn<pt8s09@aq;lcd$$uYzk2T~%h!~b zKwbi8pae=xnbsWCXw3#I4jQz-T;HteSY%ftwCLV!i`I3J+Mtw$qU}~nqg|~KH>^x) zu=yR$B^s;E7hQ|ihP2rdmTJG%XH`p^=xVj!q0&nf13~atqI{$Io2D|_?7A2@YOpI$ zSe3F+du{%umZQ;@>FS?ts{Cp*MVRh?a8x{H<A1i9YGvH66*HqPakiPE_B5)63-#HN zQ~uco+IH!z%SRuRXKMDtU!t_yVO^lX24R8Z74S6MR7h?eLS_pH=mI%WE^C0$D>l+4 zoutxalSn>2vjj@y6RZRZJgQNesMRXX5;IX!ZnoZo-dHP!KecMVSvo}5al;-fusBz% zC!pr(k}Okdqf%LG)ZllDa<=Kv{t{`hCgJ6Q4N(4EQ6(b)R?{r6tJ61{C(j4PUtGS@ zqO!=*p5UNeGz<Nu`ivWV9{QTZ8aHZ(&sLpn(O;{LCX`cQ&(vzYY>ifx2Yh0Y#1v=8 z$re+85SM5RF{{CTBdvDTPt9<(Fp=75;~Mg<6Igk&Kp;BNuDF>dT2`_lVfXEL?Nsf} zw%u(?Z?-vU4?LGEpW}G$FvoC{NoP(93v`yf&V+Q)035c98)`<nfmEFIoUbM|k&Pep zS!dfwS=b8o)QMv(gLP%dafyx`59k33<U;97{a&TaSIb(Iw^?x3;Iy2nMaaBfl(oud zEl<ak!G66~>LhijRYQ^!tJ)T;t~whxTz`Y~>SV8}w8(XaD4oQcC2Ra66Awhl?nIlg ziACCPx129k8MK**NPFPyYbv8vr3RLXRnd!lSM|enrS{<ti)geOc3jXaI!l2Loncv| zu-=hgP3==&=Y?TDTI@MjHtRZ}z(0@(_DN)K9xj_mjm}o;45f~?hEA2gROP#NW7)JG z`^5$tRBESf8ReGg4BDek+IMM+Mc0M&heg+lg3$t=hJ1)1NY448Tf^$22z>%^V!1xC zCR)k}1MhOYr0RwE#aIH{Z%gR1Mzl*4TF(?2>uhA4rrOcuA{%Sax{CwUN{M(B<sb)a z9a%7fL340LDz?AG(gvdy&Lrap+!5C(6R9FOyvA98(=L9H%z*~s-9?A61v)=$m*j}8 zHL97|NDcGVau=T{8xCE&kR`Dao{&3hZ)p|nMyrkrxnbk9h`f~HdS>`rXmgY9TFe>7 zBWMpgVq1;8Bj5!+&?j7OOD8@o)IQOLc5*i87pQ%i_#r0N*pjd$c&!yxldOxnTqF+o zLK_QI8)eM1JqY^Eq~m(4<65nQi<=KvUeV}ME3XQbO095Doz4m?;?9y5S_!v^64_Ee zGDG4V^G(~Sv(A=2L+6o&>u08^Oh%FOY%b#G66K<7S8ggd==5Z680D5I2EzM=DyvI+ zb6)Ps2{>~0ga-!EKk$^Wjl>PwK<94!joe!mbuUv2y2e71{TIIM;$?%af2wlgi%5Qk zA`4QBYm|#DUE3-pFZ#MpwcCv^uy~h`2tm!*J#Fny)aiN)#v^dwrn1lot!}in602(z z@5oKQ3v}FTX`Igx?-$q_(F!)>ER^<OOJVO|1dGkOmb%`X)(}<O#R0L2D7xInFnE}2 zd0;$6yYLP);Kmx6WY?}5oE77fSZKX?gCplX*bpse#L{d_T4>waWb2uk;2HT5gDz0Z zR$6|MCMjsW-Rfz%YN8C*^v89*fh~55)=?5QF0}kMDIK{wsn80v+@_M9zd8*!C+a6U zVL?qQi{6;}@YV&ESNsF6@k?ZYt<$$4sd=^p#y$(IlqsLlmgAUsgY=wEka;@Clu@e@ zn;rd&l6Z<PoISg8TJ5N$$$DU&jqq3#Z9=C@Eg$9DZ<PF8M5f=z8*3CPo$a-&UGO$n zX--FYw6iVZ6JwrWoRB__Zm^Lg)en&lc7uKx4`EAgWCFL;>7HtUBe=vO;pfssEN=Ce zDHZ#mcXW}X-BLMeQ?BC^*-}=WrNpz~8gB{u2xl2Y9imgS<;dxY6jwHSz(UbuXQE{C zQHSgAi3&koSW7ZBJyzgtj(f+8>!WCg>rYz}?VvvTCueIj)sDr|7BLi?aHB4)n2|P; zKu+YrP6BBM5<=cdc`dQ~&PJ2IM-+y);H+yo+Hm!)OlS&A!G4@h+|{S+AF(@P8nFQB zPPev<EZqD6x}>aNY>f92ofg>$f+e{Am{Ahic5PvVM}%#ZR}%%BWI3*G=U3DeNC(as z+dF@BqmQ8FBgrR~Hzb!Ht6T&M;@Cp*=*9toj_}5G>u<EyKUHO=_A^f3;eN&0vK!yg zdgg>0<#FgVsZshdw1h@!QLAL_uH@V}CTXR;>Y-e(=i(cZcjHl_TJH9We5Wc$OJe+t zK9c+d(!jIQEgcCm5@giWYvY^q7i<`hM~h7=nf`?lJzk4Wu?fzTt5&JbS7(UAU0ZRM zXzQ+I=!eM_lp1)U^Z3Au`Nr>ETnO8FFr((mbaf(mr0T{jovMixG)NkfMwS=bEBIh! zPhU-o9rt0I$1eg~r_Xlw?xLTIQrNch^C=0f5^t!_#X%xAaUxX*%WP!7RFtQdv-A9L zo1MQPGg4_&&;z?3!g<c(gr9XO<~1caAtt)(dUS=(0&7fqvAce7Hj0)4PhKc`Hx>-6 zCe<g9tdlP#FHs~5^NhtWuytbhZUlt4;NSGhZlvL^u!$G+>&`#W3VZZ<=~l{2!kG8) z&&|DFtoP}h$$vcm#?`!&_;T4HKF>&y_`-OZUgk`0K_=eNb4h5f)me|b^5qI)zI-A7 z_ijmGx<=i^PkSvdJ@6M-N|U`Z(OB19m;cL4ATNP;Q3CkfJnMPqB_cUvFy_Pgc0O6F zcf8eFni^fnSKI5$YR%QuXwT(!XQ9q-Z(9OdiV_ieg%!dT!j;0U!fnE*gxiIk!X3hH z;WNVB!e@o2gcpPth4DpN2`?NH4hvW4VUK(De8nE&e&JE!G2scVz}Y8!UD&HNua63k z311Z+7xoJWguAsQ@Uy}_!o9*CVXyG0z(TT!;0tR6p1E8ryePaR{6@G^%fYS|t`VLW zel5Hpv}rk2hp<@KFB}klAVjocN=w>Iq0l9C3q8VT1)leO^UXi%&m4dCINS4w4w+{U z9eVcAv*y`<G5X`5kK~t2%kYV|CUwm5wr#AhuTOcFcN|YU+ZP&@nu!^ne7?};BELIn z^adou8<6yfa=-QlggzB9ZcBHOP8In|FN)qshO1&;R7X1FUYn$S(?h%N74{29h3AD| z3$F=-!bMs#RV~yAhqY4ai12gasPMe-s=%|Z6<SI+S(qZ+qeZ^=3ik^<1N#Mm=U~4q z@GR_C1)hify1+BB-w}8&_JF{%u|E=cKK6*fGqS%Hcuw{=0?*3+kHGV?#|565{gd!# z;e^0auYnoHd|bFqI1<+?xYu77v>48Q5AXf<x6eKI!;IVh{oneQdGzxLEp?lgCjHR+ zr)00`XPp8P$}|-z53~oVN!^^2e!h`cWtE!qGo*)KXaG$-ohF?ii?x|%<a1p3vtVY* z2Lzr$E)*(+FA6KpH)fmGf__}MRk%&KUDzo+C_E&5LHM$;SNM+bJz>AV^U-g-@`ick zmq&hj@Vf`iz6Z^NcNu-?@66k#E$@lyWe-ukZ@?+<y6$=Yik>m{r4OdwzU0gi@TLV` z#1Rk%FF11<g11CWLF;;n3J)R&uSApPGp1@4;4tl6Mbo0;Bkd_tAgy!@b1zvFHAZmK z*;MNkCy7!*A!dpe;Mn+2tS8PB(~0Fl%qCt3u{u3Y6Qk4PGqE{{%f#eAg_Zn9_+T)6 z@LKrb)$qaZ!Ur#e4^keI`71aGw@nYAn#on(Wg9%DE~zpXFE-w?gX&MUSlYcjRWB^$ z(ZOqX-!Q~`9CS&UdQ3*(YvrqblSRh8bAo;|=re=<GUzLVelqAIgZ?q-8-xBM=r`yy zg8m}Cub`j!U$Hd2<quA`K!!!@c1E<K^Uz7qZ_{V<$PWGX0|I?_jw<?ExZ;Py2Ump; zdcp_U_hsk9#$Uc}qaGcU3+VAZQqKvzB6f7D@tVwAvnj_<JR%l+k9pv8UeQslqAx#c zokk=>>cqka4Mz)&=jmAlyAz3Sb~`-NYg1xM+0bC34d#-g<3vde_vKOc$PbQqcsm2H zou}Y6Xm^s=ZIezfufyDpsQ)qO_#uHY+7|`JY2OSu<oln)2W!FytHKBG@_uG1zn?7P z%;eQa-wz9n&G!n7&-3~xG@Ry$FgpD|_8vtqAALV2a835Oz;#((|9^4)zgNANkG}T_ zT#J8G_%`3+V4jcvr)NYkI{$yq^pC!u5}1Sep74Dkum7{h|Izn;fw{LI2+Y6b^?&y0 zAALV7Fz5Oc;gFEm|JkE|^nF-huKnl2Q6aDYvq%5v`+0$TEH4Nz3VHpXJ^DxAFA3aR z`<?KLkk|j&qkr`Mdx3kZuL`dTdHtU~`bXb`0{7Bi7ycmR^?&y0AASFyz#0nHOx&7S zHxaA@$ZiW?2+tB-9X{v{A9RHeTEhpSdzN?DchM*BVP-i#)m@d~Zc0$Ym<JBNTXU#- z5mMSMpEbK57z*B~pXH9wnK}P6CRpn++I1ZVbVH7{9lRs#SRix0Qx0AUpLsESka8#g z=ixIcck+J}K64;^us?k8RQTZA;e#i_2aksjz8XIGQutsL`(wGg9@Q^=xO?$$xO?%z zy?5P{Z?7`$SMv08dG>z%+fB<QUq)`m5C3pp22M-s&B7WpW8WRs@qGu|XYM;3soeLk zk@NR_(^T!5=GCn*rgqOpuVxz}sn^l$Iy1gz6!OWFp5YSssQA;;K5LqoZK<H!=JvNO zv!&~Fe)}tt!0G(`XY42aH)J!3Nh>T&8%Czh(|ehD_w_ct(Q~c2(It-Jvs~6nQN9o? zjmjl^P?M*6`Q@OuyNy-t)JvOktsj0X5*5~leuwDo@Gw46KXtR^QU<a*9CwrjW|jRN zRNg+$Z-4WPa2uo%_lvIsdY3T2Zj^nSt@;aeTHRC5?MGI>PZYV@*0oOW*50Z&Ve^Zu z?w6Yqr$_vns`_~;rE7g|?blN8;rEt0t6Q(S2lO^~e#>d|h;@bu_=Vb_?p);`{{8KO TlUhDHeKfxf{iCaaL?iwmfn32* literal 0 HcmV?d00001 diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index d9301228..2c4bdbb3 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -227,16 +227,29 @@ where match kind { UpdateKind::Message(mes) => { - self.handle_message(mes, &self.message_handlers).await; + self.handle_message(mes, &self.message_handlers) + .await; } UpdateKind::EditedMessage(mes) => { - self.handle_message(mes, &self.edited_message_handlers).await; + self.handle_message( + mes, + &self.edited_message_handlers, + ) + .await; } UpdateKind::ChannelPost(post) => { - self.handle_message(post, &self.channel_post_handlers).await; + self.handle_message( + post, + &self.channel_post_handlers, + ) + .await; } UpdateKind::EditedChannelPost(post) => { - self.handle_message(post, &self.edited_channel_post_handlers).await; + self.handle_message( + post, + &self.edited_channel_post_handlers, + ) + .await; } UpdateKind::InlineQuery(query) => { call!(self.inline_query_handlers, query) @@ -253,8 +266,12 @@ where .await; } - async fn handle_message(&self, message: Message, handlers: &Handlers<'a, Message, E>) { - let handler = handlers.iter().find_map(|e|{ + async fn handle_message( + &self, + message: Message, + handlers: &Handlers<'a, Message, E>, + ) { + let handler = handlers.iter().find_map(|e| { let (filter, handler) = e; if filter.test(&message) { Some(handler) diff --git a/src/network/telegram_response.rs b/src/network/telegram_response.rs index a3c77b4e..82185c0c 100644 --- a/src/network/telegram_response.rs +++ b/src/network/telegram_response.rs @@ -1,8 +1,9 @@ use reqwest::StatusCode; use crate::{ - requests::ResponseResult, types::ResponseParameters, RequestError, - types::{True, False} + requests::ResponseResult, + types::{False, ResponseParameters, True}, + RequestError, }; #[derive(Deserialize)] diff --git a/src/types/mod.rs b/src/types/mod.rs index eadb5942..4205e755 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -46,8 +46,8 @@ pub use shipping_query::*; pub use sticker::*; pub use sticker_set::*; pub use successful_payment::*; -pub use unit_true::*; pub use unit_false::*; +pub use unit_true::*; pub use update::*; pub use user::*; pub use user_profile_photos::*; diff --git a/src/types/unit_false.rs b/src/types/unit_false.rs index 78299be1..f5039f8e 100644 --- a/src/types/unit_false.rs +++ b/src/types/unit_false.rs @@ -1,7 +1,6 @@ -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde::de::Visitor; +use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; -#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)] pub struct False; impl std::convert::TryFrom<bool> for False { @@ -19,7 +18,7 @@ impl std::convert::TryFrom<bool> for False { impl<'de> Deserialize<'de> for False { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where - D: Deserializer<'de> + D: Deserializer<'de>, { deserializer.deserialize_bool(FalseVisitor) } @@ -30,7 +29,10 @@ struct FalseVisitor; impl<'de> Visitor<'de> for FalseVisitor { type Value = False; - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + fn expecting( + &self, + formatter: &mut std::fmt::Formatter, + ) -> std::fmt::Result { write!(formatter, "bool, equal to `false`") } @@ -41,7 +43,7 @@ impl<'de> Visitor<'de> for FalseVisitor { #[allow(clippy::match_bool)] match value { true => Err(E::custom("expected `false`, found `true`")), - false => Ok(False) + false => Ok(False), } } } @@ -49,7 +51,7 @@ impl<'de> Visitor<'de> for FalseVisitor { impl Serialize for False { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where - S: Serializer + S: Serializer, { serializer.serialize_bool(false) } diff --git a/src/types/unit_true.rs b/src/types/unit_true.rs index a953dcb2..ed953d46 100644 --- a/src/types/unit_true.rs +++ b/src/types/unit_true.rs @@ -3,7 +3,7 @@ use serde::{ ser::{Serialize, Serializer}, }; -#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)] pub struct True; impl std::convert::TryFrom<bool> for True { From 089ff82b2d35b53c7d440d5d5d4728fe5752c465 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 22:48:05 +0600 Subject: [PATCH 49/66] Rename Dispatcher to FilterDispatcher Related to https://github.com/telebofr/telebofr/issues/59. --- src/dispatcher/simple/mod.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 2c4bdbb3..4bcc77c1 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -38,7 +38,7 @@ type Handlers<'a, T, E> = /// use std::convert::Infallible; /// use telebofr::{ /// dispatcher::{ -/// simple::{error_policy::ErrorPolicy, Dispatcher}, +/// simple::{error_policy::ErrorPolicy, FilterDispatcher}, /// updater::polling, /// }, /// }; @@ -51,7 +51,7 @@ type Handlers<'a, T, E> = /// /// // create dispatcher which handlers can't fail /// // with error policy that just ignores all errors (that can't ever happen) -/// let mut dp = Dispatcher::<Infallible>::new(ErrorPolicy::Ignore) +/// let mut dp = FilterDispatcher::<Infallible>::new(ErrorPolicy::Ignore) /// // Add 'handler' that will handle all messages sent to the bot /// .message_handler(true, |mes: Message| { /// async move { println!("New message: {:?}", mes) } @@ -69,7 +69,7 @@ type Handlers<'a, T, E> = /// [Custom error policy]: /// crate::dispatcher::simple::error_policy::ErrorPolicy::Custom [updater]: /// crate::dispatcher::updater -pub struct Dispatcher<'a, E> { +pub struct FilterDispatcher<'a, E> { message_handlers: Handlers<'a, Message, E>, edited_message_handlers: Handlers<'a, Message, E>, channel_post_handlers: Handlers<'a, Message, E>, @@ -80,12 +80,12 @@ pub struct Dispatcher<'a, E> { error_policy: ErrorPolicy<'a, E>, } -impl<'a, E> Dispatcher<'a, E> +impl<'a, E> FilterDispatcher<'a, E> where E: std::fmt::Debug, // TODO: Is this really necessary? { pub fn new(error_policy: ErrorPolicy<'a, E>) -> Self { - Dispatcher { + FilterDispatcher { message_handlers: Vec::new(), edited_message_handlers: Vec::new(), channel_post_handlers: Vec::new(), @@ -293,13 +293,13 @@ where } #[async_trait(? Send)] -impl<'a, U, E> crate::dispatcher::Dispatcher<'a, U> for Dispatcher<'a, E> +impl<'a, U, E> crate::dispatcher::Dispatcher<'a, U> for FilterDispatcher<'a, E> where E: std::fmt::Debug, U: Updater + 'a, { async fn dispatch(&'a mut self, updater: U) { - Dispatcher::dispatch(self, updater).await + FilterDispatcher::dispatch(self, updater).await } } @@ -314,7 +314,7 @@ mod tests { use crate::{ dispatcher::{ - simple::{error_policy::ErrorPolicy, Dispatcher}, + simple::{error_policy::ErrorPolicy, FilterDispatcher}, updater::StreamUpdater, }, types::{ @@ -328,7 +328,7 @@ mod tests { let counter = &AtomicI32::new(0); let counter2 = &AtomicI32::new(0); - let mut dp = Dispatcher::<Infallible>::new(ErrorPolicy::Ignore) + let mut dp = FilterDispatcher::<Infallible>::new(ErrorPolicy::Ignore) .message_handler(true, |_mes: Message| { async move { counter.fetch_add(1, Ordering::SeqCst); From e9f68c67e9509b99932b0949632dadb4baca1693 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 22:50:59 +0600 Subject: [PATCH 50/66] Rename dispatcher.simple to dispatcher.filter --- src/dispatcher/{simple => filter}/error_policy.rs | 0 src/dispatcher/{simple => filter}/mod.rs | 10 +++++----- src/dispatcher/mod.rs | 2 +- src/requests/get_me.rs | 2 +- src/types/keyboard_button.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename src/dispatcher/{simple => filter}/error_policy.rs (100%) rename src/dispatcher/{simple => filter}/mod.rs (97%) diff --git a/src/dispatcher/simple/error_policy.rs b/src/dispatcher/filter/error_policy.rs similarity index 100% rename from src/dispatcher/simple/error_policy.rs rename to src/dispatcher/filter/error_policy.rs diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/filter/mod.rs similarity index 97% rename from src/dispatcher/simple/mod.rs rename to src/dispatcher/filter/mod.rs index 4bcc77c1..b6cf7205 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/filter/mod.rs @@ -4,7 +4,7 @@ use async_trait::async_trait; use crate::{ dispatcher::{ - filter::Filter, handler::Handler, simple::error_policy::ErrorPolicy, + filter::Filter, handler::Handler, filter::error_policy::ErrorPolicy, updater::Updater, }, types::{CallbackQuery, ChosenInlineResult, Message, Update, UpdateKind}, @@ -17,7 +17,7 @@ type Handlers<'a, T, E> = /// Dispatcher that dispatches updates from telegram. /// -/// This is 'simple' implementation with following limitations: +/// This is 'filter' implementation with following limitations: /// - Error (`E` generic parameter) _must_ implement [`std::fmt::Debug`] /// - All 'handlers' are boxed /// - Handler's fututres are also boxed @@ -38,7 +38,7 @@ type Handlers<'a, T, E> = /// use std::convert::Infallible; /// use telebofr::{ /// dispatcher::{ -/// simple::{error_policy::ErrorPolicy, FilterDispatcher}, +/// filter::{error_policy::ErrorPolicy, FilterDispatcher}, /// updater::polling, /// }, /// }; @@ -67,7 +67,7 @@ type Handlers<'a, T, E> = /// /// [`std::fmt::Debug`]: std::fmt::Debug /// [Custom error policy]: -/// crate::dispatcher::simple::error_policy::ErrorPolicy::Custom [updater]: +/// crate::dispatcher::filter::error_policy::ErrorPolicy::Custom [updater]: /// crate::dispatcher::updater pub struct FilterDispatcher<'a, E> { message_handlers: Handlers<'a, Message, E>, @@ -314,7 +314,7 @@ mod tests { use crate::{ dispatcher::{ - simple::{error_policy::ErrorPolicy, FilterDispatcher}, + filter::{error_policy::ErrorPolicy, FilterDispatcher}, updater::StreamUpdater, }, types::{ diff --git a/src/dispatcher/mod.rs b/src/dispatcher/mod.rs index 06f2471d..c13fb8b9 100644 --- a/src/dispatcher/mod.rs +++ b/src/dispatcher/mod.rs @@ -6,7 +6,7 @@ pub use handler::Handler; pub mod filter; pub mod handler; -pub mod simple; +pub mod filter; pub mod updater; #[async_trait(? Send)] diff --git a/src/requests/get_me.rs b/src/requests/get_me.rs index 29d5a546..6efe9543 100644 --- a/src/requests/get_me.rs +++ b/src/requests/get_me.rs @@ -8,7 +8,7 @@ use crate::{ }; #[derive(Debug, Clone)] -/// A simple method for testing your bot's auth token. Requires no parameters. +/// A filter method for testing your bot's auth token. Requires no parameters. /// Returns basic information about the bot in form of a [`User`] object. pub struct GetMe<'a> { bot: &'a Bot, diff --git a/src/types/keyboard_button.rs b/src/types/keyboard_button.rs index 41d1b156..01929838 100644 --- a/src/types/keyboard_button.rs +++ b/src/types/keyboard_button.rs @@ -1,4 +1,4 @@ -/// This object represents one button of the reply keyboard. For simple text +/// This object represents one button of the reply keyboard. For filter text /// buttons String can be used instead of this object to specify text of the /// button. Optional fields are mutually exclusive. #[derive(Debug, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)] From 2bd8734482058ca0e995f45778d8cf30d1329fb2 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 22:52:48 +0600 Subject: [PATCH 51/66] Rename 'dispatcher' to 'dispatching' --- .../filter/error_policy.rs | 0 src/{dispatcher => dispatching}/filter/mod.rs | 10 ++-- .../filter.rs => dispatching/filters.rs} | 46 +++++++++---------- src/{dispatcher => dispatching}/handler.rs | 0 src/{dispatcher => dispatching}/mod.rs | 4 +- src/{dispatcher => dispatching}/updater.rs | 0 src/lib.rs | 2 +- 7 files changed, 31 insertions(+), 31 deletions(-) rename src/{dispatcher => dispatching}/filter/error_policy.rs (100%) rename src/{dispatcher => dispatching}/filter/mod.rs (98%) rename src/{dispatcher/filter.rs => dispatching/filters.rs} (86%) rename src/{dispatcher => dispatching}/handler.rs (100%) rename src/{dispatcher => dispatching}/mod.rs (87%) rename src/{dispatcher => dispatching}/updater.rs (100%) diff --git a/src/dispatcher/filter/error_policy.rs b/src/dispatching/filter/error_policy.rs similarity index 100% rename from src/dispatcher/filter/error_policy.rs rename to src/dispatching/filter/error_policy.rs diff --git a/src/dispatcher/filter/mod.rs b/src/dispatching/filter/mod.rs similarity index 98% rename from src/dispatcher/filter/mod.rs rename to src/dispatching/filter/mod.rs index b6cf7205..6645b41e 100644 --- a/src/dispatcher/filter/mod.rs +++ b/src/dispatching/filter/mod.rs @@ -23,7 +23,7 @@ type Handlers<'a, T, E> = /// - Handler's fututres are also boxed /// - [Custom error policy] is also boxed /// - All errors from [updater] are ignored (TODO: remove this limitation) -/// - All handlers executed in order (this means that in dispatcher have 2 +/// - All handlers executed in order (this means that in dispatching have 2 /// upadtes it will first execute some handler into complition with first /// update and **then** search for handler for second update, this is probably /// wrong) @@ -37,7 +37,7 @@ type Handlers<'a, T, E> = /// async fn run() { /// use std::convert::Infallible; /// use telebofr::{ -/// dispatcher::{ +/// dispatching::{ /// filter::{error_policy::ErrorPolicy, FilterDispatcher}, /// updater::polling, /// }, @@ -49,7 +49,7 @@ type Handlers<'a, T, E> = /// /// let bot = Bot::new("TOKEN"); /// -/// // create dispatcher which handlers can't fail +/// // create dispatching which handlers can't fail /// // with error policy that just ignores all errors (that can't ever happen) /// let mut dp = FilterDispatcher::<Infallible>::new(ErrorPolicy::Ignore) /// // Add 'handler' that will handle all messages sent to the bot @@ -67,8 +67,8 @@ type Handlers<'a, T, E> = /// /// [`std::fmt::Debug`]: std::fmt::Debug /// [Custom error policy]: -/// crate::dispatcher::filter::error_policy::ErrorPolicy::Custom [updater]: -/// crate::dispatcher::updater +/// crate::dispatching::filter::error_policy::ErrorPolicy::Custom [updater]: +/// crate::dispatching::updater pub struct FilterDispatcher<'a, E> { message_handlers: Handlers<'a, Message, E>, edited_message_handlers: Handlers<'a, Message, E>, diff --git a/src/dispatcher/filter.rs b/src/dispatching/filters.rs similarity index 86% rename from src/dispatcher/filter.rs rename to src/dispatching/filters.rs index bcb59f16..6317a2e3 100644 --- a/src/dispatcher/filter.rs +++ b/src/dispatching/filters.rs @@ -6,7 +6,7 @@ pub trait Filter<T> { } /// ``` -/// use telebofr::dispatcher::filter::Filter; +/// use telebofr::dispatching::filter::Filter; /// /// let closure = |i: &i32| -> bool { *i >= 42 }; /// assert!(closure.test(&42)); @@ -22,7 +22,7 @@ impl<T, F: Fn(&T) -> bool> Filter<T> for F { } /// ``` -/// use telebofr::dispatcher::filter::Filter; +/// use telebofr::dispatching::filter::Filter; /// /// assert!(true.test(&())); /// assert_eq!(false.test(&()), false); @@ -42,7 +42,7 @@ impl<T> Filter<T> for bool { /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{And, Filter}; +/// use telebofr::dispatching::filter::{And, Filter}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert_eq!(And::new(true, false).test(&()), false); @@ -73,13 +73,13 @@ where /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{and, Filter}; +/// use telebofr::dispatching::filter::{and, Filter}; /// /// assert!(and(true, true).test(&())); /// assert_eq!(and(true, false).test(&()), false); /// ``` /// -/// [`And::new`]: crate::dispatcher::filter::And::new +/// [`And::new`]: crate::dispatching::filter::And::new pub fn and<A, B>(a: A, b: B) -> And<A, B> { And::new(a, b) } @@ -93,7 +93,7 @@ pub fn and<A, B>(a: A, b: B) -> And<A, B> { /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{Filter, Or}; +/// use telebofr::dispatching::filter::{Filter, Or}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Or::new(true, false).test(&())); @@ -124,13 +124,13 @@ where /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{or, Filter}; +/// use telebofr::dispatching::filter::{or, Filter}; /// /// assert!(or(true, false).test(&())); /// assert_eq!(or(false, false).test(&()), false); /// ``` /// -/// [`Or::new`]: crate::dispatcher::filter::Or::new +/// [`Or::new`]: crate::dispatching::filter::Or::new pub fn or<A, B>(a: A, b: B) -> Or<A, B> { Or::new(a, b) } @@ -141,7 +141,7 @@ pub fn or<A, B>(a: A, b: B) -> Or<A, B> { /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{Filter, Not}; +/// use telebofr::dispatching::filter::{Filter, Not}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Not::new(false).test(&())); @@ -169,13 +169,13 @@ where /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{not, Filter}; +/// use telebofr::dispatching::filter::{not, Filter}; /// /// assert!(not(false).test(&())); /// assert_eq!(not(true).test(&()), false); /// ``` /// -/// [`Not::new`]: crate::dispatcher::filter::Not::new +/// [`Not::new`]: crate::dispatching::filter::Not::new pub fn not<A>(a: A) -> Not<A> { Not::new(a) } @@ -187,7 +187,7 @@ pub fn not<A>(a: A) -> Not<A> { /// /// ## Examples /// ``` -/// use telebofr::{all, dispatcher::filter::Filter}; +/// use telebofr::{all, dispatching::filter::Filter}; /// /// assert!(all![true].test(&())); /// assert!(all![true, true].test(&())); @@ -199,7 +199,7 @@ pub fn not<A>(a: A) -> Not<A> { /// assert_eq!(all![false, false].test(&()), false); /// ``` /// -/// [filter]: crate::dispatcher::filter::Filter +/// [filter]: crate::dispatching::filter::Filter #[macro_export] macro_rules! all { ($one:expr) => { $one }; @@ -218,7 +218,7 @@ macro_rules! all { /// /// ## Examples /// ``` -/// use telebofr::{any, dispatcher::filter::Filter}; +/// use telebofr::{any, dispatching::filter::Filter}; /// /// assert!(any![true].test(&())); /// assert!(any![true, true].test(&())); @@ -230,7 +230,7 @@ macro_rules! all { /// assert_eq!(any![false, false, false].test(&()), false); /// ``` /// -/// [filter]: crate::dispatcher::filter::Filter +/// [filter]: crate::dispatching::filter::Filter #[macro_export] macro_rules! any { ($one:expr) => { $one }; @@ -246,7 +246,7 @@ macro_rules! any { /// /// ## Examples /// ``` -/// use telebofr::dispatcher::filter::{f, And, Filter, Or, F}; +/// use telebofr::dispatching::filter::{f, And, Filter, Or, F}; /// /// let flt1 = |i: &i32| -> bool { *i > 17 }; /// let flt2 = |i: &i32| -> bool { *i < 42 }; @@ -277,7 +277,7 @@ pub struct F<A>(A); /// Constructor fn for [F] /// -/// [F]: crate::dispatcher::filter::F; +/// [F]: crate::dispatching::filter::F; pub fn f<A>(a: A) -> F<A> { F(a) } @@ -314,7 +314,7 @@ pub trait FilterExt<T> { /// /// ## Examples /// ``` - /// use telebofr::dispatcher::filter::{Filter, FilterExt}; + /// use telebofr::dispatching::filter::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i > 0 }; /// let flt = flt.not(); @@ -322,7 +322,7 @@ pub trait FilterExt<T> { /// assert_eq!(flt.test(&1), false); /// ``` /// - /// [`Not::new`]: crate::dispatcher::filter::Not::new + /// [`Not::new`]: crate::dispatching::filter::Not::new fn not(self) -> Not<Self> where Self: Sized, @@ -334,7 +334,7 @@ pub trait FilterExt<T> { /// /// ## Examples /// ``` - /// use telebofr::dispatcher::filter::{Filter, FilterExt}; + /// use telebofr::dispatching::filter::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i > 0 }; /// let flt = flt.and(|i: &i32| *i < 42); @@ -344,7 +344,7 @@ pub trait FilterExt<T> { /// assert_eq!(flt.test(&43), false); /// ``` /// - /// [`Not::new`]: crate::dispatcher::filter::And::new + /// [`Not::new`]: crate::dispatching::filter::And::new fn and<B>(self, other: B) -> And<Self, B> where Self: Sized, @@ -356,7 +356,7 @@ pub trait FilterExt<T> { /// /// ## Examples /// ``` - /// use telebofr::dispatcher::filter::{Filter, FilterExt}; + /// use telebofr::dispatching::filter::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i < 0 }; /// let flt = flt.or(|i: &i32| *i > 42); @@ -366,7 +366,7 @@ pub trait FilterExt<T> { /// assert_eq!(flt.test(&17), false); /// ``` /// - /// [`Not::new`]: crate::dispatcher::filter::Or::new + /// [`Not::new`]: crate::dispatching::filter::Or::new fn or<B>(self, other: B) -> Or<Self, B> where Self: Sized, diff --git a/src/dispatcher/handler.rs b/src/dispatching/handler.rs similarity index 100% rename from src/dispatcher/handler.rs rename to src/dispatching/handler.rs diff --git a/src/dispatcher/mod.rs b/src/dispatching/mod.rs similarity index 87% rename from src/dispatcher/mod.rs rename to src/dispatching/mod.rs index c13fb8b9..6c5cc912 100644 --- a/src/dispatcher/mod.rs +++ b/src/dispatching/mod.rs @@ -4,9 +4,9 @@ use async_trait::async_trait; pub use filter::Filter; pub use handler::Handler; -pub mod filter; +pub mod filters; pub mod handler; -pub mod filter; +pub mod filters; pub mod updater; #[async_trait(? Send)] diff --git a/src/dispatcher/updater.rs b/src/dispatching/updater.rs similarity index 100% rename from src/dispatcher/updater.rs rename to src/dispatching/updater.rs diff --git a/src/lib.rs b/src/lib.rs index 533071c7..838a211a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,6 @@ mod errors; mod network; mod bot; -pub mod dispatcher; +pub mod dispatching; pub mod requests; pub mod types; From 7268c39c8867c69009591685c45e25832cf7e9d1 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 22:53:33 +0600 Subject: [PATCH 52/66] Create dispatching.dispatchers --- src/dispatching/{ => dispatchers}/filter/error_policy.rs | 0 src/dispatching/{ => dispatchers}/filter/mod.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/dispatching/{ => dispatchers}/filter/error_policy.rs (100%) rename src/dispatching/{ => dispatchers}/filter/mod.rs (100%) diff --git a/src/dispatching/filter/error_policy.rs b/src/dispatching/dispatchers/filter/error_policy.rs similarity index 100% rename from src/dispatching/filter/error_policy.rs rename to src/dispatching/dispatchers/filter/error_policy.rs diff --git a/src/dispatching/filter/mod.rs b/src/dispatching/dispatchers/filter/mod.rs similarity index 100% rename from src/dispatching/filter/mod.rs rename to src/dispatching/dispatchers/filter/mod.rs From ecf2aec3962a14220baf818b9bc839b22c9bd4e0 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 23:06:12 +0600 Subject: [PATCH 53/66] Fix all the errors --- src/dispatching/dispatchers/filter/mod.rs | 16 ++++--- src/dispatching/dispatchers/mod.rs | 3 ++ src/dispatching/filters.rs | 32 +++++++------- src/dispatching/mod.rs | 4 +- src/requests/answer_callback_query.rs | 3 +- src/requests/delete_chat_sticker_set.rs | 3 +- src/requests/get_chat_administrators.rs | 3 +- src/requests/get_chat_member.rs | 3 +- src/requests/mod.rs | 2 +- src/requests/set_chat_sticker_set.rs | 3 +- src/types/mod.rs | 54 +++++++++++------------ 11 files changed, 67 insertions(+), 59 deletions(-) create mode 100644 src/dispatching/dispatchers/mod.rs diff --git a/src/dispatching/dispatchers/filter/mod.rs b/src/dispatching/dispatchers/filter/mod.rs index 6645b41e..6689120e 100644 --- a/src/dispatching/dispatchers/filter/mod.rs +++ b/src/dispatching/dispatchers/filter/mod.rs @@ -3,9 +3,9 @@ use futures::StreamExt; use async_trait::async_trait; use crate::{ - dispatcher::{ - filter::Filter, handler::Handler, filter::error_policy::ErrorPolicy, - updater::Updater, + dispatching::{ + dispatchers::filter::error_policy::ErrorPolicy, filters::Filter, + handler::Handler, updater::Updater, }, types::{CallbackQuery, ChosenInlineResult, Message, Update, UpdateKind}, }; @@ -38,7 +38,7 @@ type Handlers<'a, T, E> = /// use std::convert::Infallible; /// use telebofr::{ /// dispatching::{ -/// filter::{error_policy::ErrorPolicy, FilterDispatcher}, +/// dispatchers::filter::{error_policy::ErrorPolicy, FilterDispatcher}, /// updater::polling, /// }, /// }; @@ -293,7 +293,7 @@ where } #[async_trait(? Send)] -impl<'a, U, E> crate::dispatcher::Dispatcher<'a, U> for FilterDispatcher<'a, E> +impl<'a, U, E> crate::dispatching::Dispatcher<'a, U> for FilterDispatcher<'a, E> where E: std::fmt::Debug, U: Updater + 'a, @@ -313,8 +313,10 @@ mod tests { use futures::Stream; use crate::{ - dispatcher::{ - filter::{error_policy::ErrorPolicy, FilterDispatcher}, + dispatching::{ + dispatchers::filter::{ + error_policy::ErrorPolicy, FilterDispatcher, + }, updater::StreamUpdater, }, types::{ diff --git a/src/dispatching/dispatchers/mod.rs b/src/dispatching/dispatchers/mod.rs new file mode 100644 index 00000000..1ec549e1 --- /dev/null +++ b/src/dispatching/dispatchers/mod.rs @@ -0,0 +1,3 @@ +pub use filter::FilterDispatcher; + +pub mod filter; diff --git a/src/dispatching/filters.rs b/src/dispatching/filters.rs index 6317a2e3..8c513405 100644 --- a/src/dispatching/filters.rs +++ b/src/dispatching/filters.rs @@ -6,7 +6,7 @@ pub trait Filter<T> { } /// ``` -/// use telebofr::dispatching::filter::Filter; +/// use telebofr::dispatching::filters::Filter; /// /// let closure = |i: &i32| -> bool { *i >= 42 }; /// assert!(closure.test(&42)); @@ -22,7 +22,7 @@ impl<T, F: Fn(&T) -> bool> Filter<T> for F { } /// ``` -/// use telebofr::dispatching::filter::Filter; +/// use telebofr::dispatching::filters::Filter; /// /// assert!(true.test(&())); /// assert_eq!(false.test(&()), false); @@ -42,7 +42,7 @@ impl<T> Filter<T> for bool { /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{And, Filter}; +/// use telebofr::dispatching::filters::{And, Filter}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert_eq!(And::new(true, false).test(&()), false); @@ -73,7 +73,7 @@ where /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{and, Filter}; +/// use telebofr::dispatching::filters::{and, Filter}; /// /// assert!(and(true, true).test(&())); /// assert_eq!(and(true, false).test(&()), false); @@ -93,7 +93,7 @@ pub fn and<A, B>(a: A, b: B) -> And<A, B> { /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{Filter, Or}; +/// use telebofr::dispatching::filters::{Filter, Or}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Or::new(true, false).test(&())); @@ -124,7 +124,7 @@ where /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{or, Filter}; +/// use telebofr::dispatching::filters::{or, Filter}; /// /// assert!(or(true, false).test(&())); /// assert_eq!(or(false, false).test(&()), false); @@ -141,7 +141,7 @@ pub fn or<A, B>(a: A, b: B) -> Or<A, B> { /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{Filter, Not}; +/// use telebofr::dispatching::filters::{Filter, Not}; /// /// // Note: bool can be treated as `Filter` that always return self. /// assert!(Not::new(false).test(&())); @@ -169,7 +169,7 @@ where /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{not, Filter}; +/// use telebofr::dispatching::filters::{not, Filter}; /// /// assert!(not(false).test(&())); /// assert_eq!(not(true).test(&()), false); @@ -187,7 +187,7 @@ pub fn not<A>(a: A) -> Not<A> { /// /// ## Examples /// ``` -/// use telebofr::{all, dispatching::filter::Filter}; +/// use telebofr::{all, dispatching::filters::Filter}; /// /// assert!(all![true].test(&())); /// assert!(all![true, true].test(&())); @@ -204,7 +204,7 @@ pub fn not<A>(a: A) -> Not<A> { macro_rules! all { ($one:expr) => { $one }; ($head:expr, $($tail:tt)+) => { - $crate::dispatcher::filter::And::new( + $crate::dispatching::filters::And::new( $head, $crate::all!($($tail)+) ) @@ -218,7 +218,7 @@ macro_rules! all { /// /// ## Examples /// ``` -/// use telebofr::{any, dispatching::filter::Filter}; +/// use telebofr::{any, dispatching::filters::Filter}; /// /// assert!(any![true].test(&())); /// assert!(any![true, true].test(&())); @@ -235,7 +235,7 @@ macro_rules! all { macro_rules! any { ($one:expr) => { $one }; ($head:expr, $($tail:tt)+) => { - $crate::dispatcher::filter::Or::new( + $crate::dispatching::filters::Or::new( $head, $crate::all!($($tail)+) ) @@ -246,7 +246,7 @@ macro_rules! any { /// /// ## Examples /// ``` -/// use telebofr::dispatching::filter::{f, And, Filter, Or, F}; +/// use telebofr::dispatching::filters::{f, And, Filter, Or, F}; /// /// let flt1 = |i: &i32| -> bool { *i > 17 }; /// let flt2 = |i: &i32| -> bool { *i < 42 }; @@ -314,7 +314,7 @@ pub trait FilterExt<T> { /// /// ## Examples /// ``` - /// use telebofr::dispatching::filter::{Filter, FilterExt}; + /// use telebofr::dispatching::filters::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i > 0 }; /// let flt = flt.not(); @@ -334,7 +334,7 @@ pub trait FilterExt<T> { /// /// ## Examples /// ``` - /// use telebofr::dispatching::filter::{Filter, FilterExt}; + /// use telebofr::dispatching::filters::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i > 0 }; /// let flt = flt.and(|i: &i32| *i < 42); @@ -356,7 +356,7 @@ pub trait FilterExt<T> { /// /// ## Examples /// ``` - /// use telebofr::dispatching::filter::{Filter, FilterExt}; + /// use telebofr::dispatching::filters::{Filter, FilterExt}; /// /// let flt = |i: &i32| -> bool { *i < 0 }; /// let flt = flt.or(|i: &i32| *i > 42); diff --git a/src/dispatching/mod.rs b/src/dispatching/mod.rs index 6c5cc912..c239778f 100644 --- a/src/dispatching/mod.rs +++ b/src/dispatching/mod.rs @@ -1,12 +1,12 @@ //! Update dispatching. use async_trait::async_trait; -pub use filter::Filter; +pub use filters::Filter; pub use handler::Handler; +pub mod dispatchers; pub mod filters; pub mod handler; -pub mod filters; pub mod updater; #[async_trait(? Send)] diff --git a/src/requests/answer_callback_query.rs b/src/requests/answer_callback_query.rs index 9d62af18..6bc42024 100644 --- a/src/requests/answer_callback_query.rs +++ b/src/requests/answer_callback_query.rs @@ -1,10 +1,11 @@ +use async_trait::async_trait; + use crate::{ bot::Bot, network, requests::{Request, ResponseResult}, types::True, }; -use async_trait::async_trait; /// Use this method to send answers to callback queries sent from inline /// keyboards. The answer will be displayed to the user as a notification at the diff --git a/src/requests/delete_chat_sticker_set.rs b/src/requests/delete_chat_sticker_set.rs index 2d1c849c..63a5260f 100644 --- a/src/requests/delete_chat_sticker_set.rs +++ b/src/requests/delete_chat_sticker_set.rs @@ -1,10 +1,11 @@ +use async_trait::async_trait; + use crate::{ bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, True}, }; -use async_trait::async_trait; /// Use this method to delete a group sticker set from a supergroup. The bot /// must be an administrator in the chat for this to work and must have the diff --git a/src/requests/get_chat_administrators.rs b/src/requests/get_chat_administrators.rs index f80c63c9..ba35a99c 100644 --- a/src/requests/get_chat_administrators.rs +++ b/src/requests/get_chat_administrators.rs @@ -1,10 +1,11 @@ +use async_trait::async_trait; + use crate::{ bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, ChatMember}, }; -use async_trait::async_trait; /// Use this method to get a list of administrators in a chat. On success, /// returns an Array of ChatMember objects that contains information about all diff --git a/src/requests/get_chat_member.rs b/src/requests/get_chat_member.rs index ce3eae65..3a03fd12 100644 --- a/src/requests/get_chat_member.rs +++ b/src/requests/get_chat_member.rs @@ -1,10 +1,11 @@ +use async_trait::async_trait; + use crate::{ bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, ChatMember}, }; -use async_trait::async_trait; /// Use this method to get information about a member of a chat. Returns a /// ChatMember object on success. diff --git a/src/requests/mod.rs b/src/requests/mod.rs index 5349630b..a98d12d9 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -1,11 +1,11 @@ //! API requests. -use async_trait::async_trait; use serde::de::DeserializeOwned; pub use answer_callback_query::*; pub use answer_pre_checkout_query::*; pub use answer_shipping_query::*; +use async_trait::async_trait; pub use delete_chat_photo::*; pub use delete_chat_sticker_set::*; pub use edit_message_live_location::*; diff --git a/src/requests/set_chat_sticker_set.rs b/src/requests/set_chat_sticker_set.rs index f27d82d5..a6166cf5 100644 --- a/src/requests/set_chat_sticker_set.rs +++ b/src/requests/set_chat_sticker_set.rs @@ -1,10 +1,11 @@ +use async_trait::async_trait; + use crate::{ bot::Bot, network, requests::{Request, ResponseResult}, types::{ChatId, True}, }; -use async_trait::async_trait; /// Use this method to set a new group sticker set for a supergroup. The bot /// must be an administrator in the chat for this to work and must have the diff --git a/src/types/mod.rs b/src/types/mod.rs index 4205e755..075b1dfc 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -13,12 +13,36 @@ pub use chat_photo::*; pub use chosen_inline_result::*; pub use contact::*; pub use document::*; +pub use encrypted_credentials::*; +pub use encrypted_passport_element::*; pub use file::*; pub use force_reply::*; pub use game::*; pub use game_high_score::*; pub use inline_keyboard_button::*; pub use inline_keyboard_markup::*; +pub use inline_query::*; +pub use inline_query_result::*; +pub use inline_query_result_article::*; +pub use inline_query_result_audio::*; +pub use inline_query_result_cached_audio::*; +pub use inline_query_result_cached_document::*; +pub use inline_query_result_cached_gif::*; +pub use inline_query_result_cached_mpeg4_gif::*; +pub use inline_query_result_cached_photo::*; +pub use inline_query_result_cached_sticker::*; +pub use inline_query_result_cached_video::*; +pub use inline_query_result_cached_voice::*; +pub use inline_query_result_contact::*; +pub use inline_query_result_document::*; +pub use inline_query_result_game::*; +pub use inline_query_result_gif::*; +pub use inline_query_result_location::*; +pub use inline_query_result_mpeg4_gif::*; +pub use inline_query_result_photo::*; +pub use inline_query_result_venue::*; +pub use inline_query_result_video::*; +pub use inline_query_result_voice::*; pub use input_file::*; pub use input_media::*; pub use input_message_content::*; @@ -32,6 +56,8 @@ pub use message::*; pub use message_entity::*; pub use order_info::*; pub use parse_mode::*; +pub use passport_data::*; +pub use passport_file::*; pub use photo_size::*; pub use poll::*; pub use pre_checkout_query::*; @@ -57,34 +83,6 @@ pub use video_note::*; pub use voice::*; pub use webhook_info::*; -pub use inline_query::*; -pub use inline_query_result::*; -pub use inline_query_result_article::*; -pub use inline_query_result_audio::*; -pub use inline_query_result_cached_audio::*; -pub use inline_query_result_cached_document::*; -pub use inline_query_result_cached_gif::*; -pub use inline_query_result_cached_mpeg4_gif::*; -pub use inline_query_result_cached_photo::*; -pub use inline_query_result_cached_sticker::*; -pub use inline_query_result_cached_video::*; -pub use inline_query_result_cached_voice::*; -pub use inline_query_result_contact::*; -pub use inline_query_result_document::*; -pub use inline_query_result_game::*; -pub use inline_query_result_gif::*; -pub use inline_query_result_location::*; -pub use inline_query_result_mpeg4_gif::*; -pub use inline_query_result_photo::*; -pub use inline_query_result_venue::*; -pub use inline_query_result_video::*; -pub use inline_query_result_voice::*; - -pub use encrypted_credentials::*; -pub use encrypted_passport_element::*; -pub use passport_data::*; -pub use passport_file::*; - mod animation; mod audio; mod callback_game; From c611fce15b65f77b1d2bcd24f85d991e626324c8 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Sun, 20 Oct 2019 23:21:47 +0600 Subject: [PATCH 54/66] Fix --- src/requests/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/requests/mod.rs b/src/requests/mod.rs index a98d12d9..e9bbc265 100644 --- a/src/requests/mod.rs +++ b/src/requests/mod.rs @@ -1,11 +1,8 @@ //! API requests. -use serde::de::DeserializeOwned; - pub use answer_callback_query::*; pub use answer_pre_checkout_query::*; pub use answer_shipping_query::*; -use async_trait::async_trait; pub use delete_chat_photo::*; pub use delete_chat_sticker_set::*; pub use edit_message_live_location::*; @@ -94,6 +91,9 @@ mod stop_message_live_location; mod unban_chat_member; mod unpin_chat_message; +use async_trait::async_trait; +use serde::de::DeserializeOwned; + /// A type that is returned from `Request::send_boxed`. pub type ResponseResult<T> = Result<T, crate::RequestError>; From b2a88e51eba66a5b3186fc636f70e0dbc042426c Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Mon, 21 Oct 2019 13:30:17 +0300 Subject: [PATCH 55/66] replaced macro call! to function handle() --- src/dispatcher/simple/mod.rs | 68 ++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/dispatcher/simple/mod.rs b/src/dispatcher/simple/mod.rs index 5c7048f5..35f385ff 100644 --- a/src/dispatcher/simple/mod.rs +++ b/src/dispatcher/simple/mod.rs @@ -195,63 +195,57 @@ where kind = kind ); - // TODO: can someone extract this to a function? - macro_rules! call { - ($h:expr, $value:expr) => {{ - let value = $value; - let handler = $h.iter().find_map(|e| { - let (filter, handler) = e; - if filter.test(&value) { - Some(handler) - } else { - None - } - }); - - match handler { - Some(handler) => { - if let Err(err) = - handler.handle(value).await - { - self.error_policy - .handle_error(err) - .await; - } - } - None => { - log::warn!("Unhandled update: {:?}", value) - } - } - }}; - } - match kind { UpdateKind::Message(mes) => { - call!(self.message_handlers, mes) + self.handle(mes, &self.message_handlers).await; } UpdateKind::EditedMessage(mes) => { - call!(self.edited_message_handlers, mes) + self.handle(mes, &self.edited_message_handlers).await; } UpdateKind::ChannelPost(post) => { - call!(self.channel_post_handlers, post) + self.handle(post, &self.channel_post_handlers).await; } UpdateKind::EditedChannelPost(post) => { - call!(self.edited_channel_post_handlers, post) + self.handle(post, &self.edited_channel_post_handlers).await; } UpdateKind::InlineQuery(query) => { - call!(self.inline_query_handlers, query) + self.handle(query, &self.inline_query_handlers).await; } UpdateKind::ChosenInlineResult(result) => { - call!(self.chosen_inline_result_handlers, result) + self.handle(result, &self.chosen_inline_result_handlers).await; } UpdateKind::CallbackQuery(callback) => { - call!(self.callback_query_handlers, callback) + self.handle(callback, &self.callback_query_handlers).await; } } } }) .await; } + + async fn handle<T>(&self, update: T, handlers: &Handlers<'a, T, E>) + where + T: std::fmt::Debug + { + let handler = handlers.iter().find_map(|e|{ + let (filter, handler) = e; + if filter.test(&update) { + Some(handler) + } else { + None + } + }); + match handler { + Some(handler) => { + if let Err(err) = handler.handle(update).await { + self.error_policy.handle_error(err).await + } + } + None => { + log::warn!("unhandled update {:?}", update); + } + } + } } #[async_trait(? Send)] From 37ab5e049af06b571874ee49beb547307bceca2c Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Tue, 22 Oct 2019 17:02:43 +0600 Subject: [PATCH 56/66] Fmt --- src/dispatching/dispatchers/filter/mod.rs | 41 ++++++++++++----------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/dispatching/dispatchers/filter/mod.rs b/src/dispatching/dispatchers/filter/mod.rs index 21038627..b3ed259f 100644 --- a/src/dispatching/dispatchers/filter/mod.rs +++ b/src/dispatching/dispatchers/filter/mod.rs @@ -5,7 +5,7 @@ use async_trait::async_trait; use crate::{ dispatching::{ dispatchers::filter::error_policy::ErrorPolicy, filters::Filter, - handler::Handler, updater::Updater, + handler::Handler, updater::Updater, Dispatcher, }, types::{CallbackQuery, ChosenInlineResult, Message, Update, UpdateKind}, }; @@ -197,22 +197,15 @@ where match kind { UpdateKind::Message(mes) => { - self.handle(mes, &self.message_handlers) - .await; + self.handle(mes, &self.message_handlers).await } UpdateKind::EditedMessage(mes) => { - self.handle( - mes, - &self.edited_message_handlers, - ) - .await; + self.handle(mes, &self.edited_message_handlers) + .await; } UpdateKind::ChannelPost(post) => { - self.handle( - post, - &self.channel_post_handlers, - ) - .await; + self.handle(post, &self.channel_post_handlers) + .await; } UpdateKind::EditedChannelPost(post) => { self.handle( @@ -222,13 +215,22 @@ where .await; } UpdateKind::InlineQuery(query) => { - self.handle(query, &self.inline_query_handlers).await; + self.handle(query, &self.inline_query_handlers) + .await; } UpdateKind::ChosenInlineResult(result) => { - self.handle(result, &self.chosen_inline_result_handlers).await; + self.handle( + result, + &self.chosen_inline_result_handlers, + ) + .await; } UpdateKind::CallbackQuery(callback) => { - self.handle(callback, &self.callback_query_handlers).await; + self.handle( + callback, + &self.callback_query_handlers, + ) + .await; } } } @@ -238,9 +240,9 @@ where async fn handle<T>(&self, update: T, handlers: &Handlers<'a, T, E>) where - T: std::fmt::Debug + T: std::fmt::Debug, { - let handler = handlers.iter().find_map(|e|{ + let handler = handlers.iter().find_map(|e| { let (filter, handler) = e; if filter.test(&update) { Some(handler) @@ -248,6 +250,7 @@ where None } }); + match handler { Some(handler) => { if let Err(err) = handler.handle(update).await { @@ -262,7 +265,7 @@ where } #[async_trait(? Send)] -impl<'a, U, E> crate::dispatching::Dispatcher<'a, U> for FilterDispatcher<'a, E> +impl<'a, U, E> Dispatcher<'a, U> for FilterDispatcher<'a, E> where E: std::fmt::Debug, U: Updater + 'a, From ec11b9ed3abdb49842dd6e86f11eebe9ce361dda Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 12:56:44 +0300 Subject: [PATCH 57/66] add MessageTextFilter --- .../dispatchers/filter/filters/mod.rs | 3 + .../dispatchers/filter/filters/text.rs | 82 +++++++++++++++++++ src/dispatching/dispatchers/filter/mod.rs | 1 + 3 files changed, 86 insertions(+) create mode 100644 src/dispatching/dispatchers/filter/filters/mod.rs create mode 100644 src/dispatching/dispatchers/filter/filters/text.rs diff --git a/src/dispatching/dispatchers/filter/filters/mod.rs b/src/dispatching/dispatchers/filter/filters/mod.rs new file mode 100644 index 00000000..45eaf476 --- /dev/null +++ b/src/dispatching/dispatchers/filter/filters/mod.rs @@ -0,0 +1,3 @@ +pub use text::*; + +mod text; \ No newline at end of file diff --git a/src/dispatching/dispatchers/filter/filters/text.rs b/src/dispatching/dispatchers/filter/filters/text.rs new file mode 100644 index 00000000..2bb76a0e --- /dev/null +++ b/src/dispatching/dispatchers/filter/filters/text.rs @@ -0,0 +1,82 @@ +use crate::dispatching::Filter; +use crate::types::Message; + +pub struct MessageTextFilter { + text: String, +} + +impl Filter<Message> for MessageTextFilter { + fn test(&self, value: &Message) -> bool { + match value.text() { + Some(text) => self.text == text, + None => false + } + } +} + +impl MessageTextFilter { + pub fn new(text: String) -> Self { + Self { + text + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn texts_are_equal() { + let filter = MessageTextFilter::new("text".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "text" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert!(filter.test(&message)); + } + + #[test] + fn texts_are_not_equal() { + let filter = MessageTextFilter::new("text".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "not equal text" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert_eq!(filter.test(&message), false); + } +} \ No newline at end of file diff --git a/src/dispatching/dispatchers/filter/mod.rs b/src/dispatching/dispatchers/filter/mod.rs index b3ed259f..816867fc 100644 --- a/src/dispatching/dispatchers/filter/mod.rs +++ b/src/dispatching/dispatchers/filter/mod.rs @@ -10,6 +10,7 @@ use crate::{ types::{CallbackQuery, ChosenInlineResult, Message, Update, UpdateKind}, }; +pub mod filters; pub mod error_policy; type Handlers<'a, T, E> = From 03b0e41fa0b2a926aa9b6d0548ed25721e39a5a6 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 12:59:58 +0300 Subject: [PATCH 58/66] added test caption --- src/dispatching/dispatchers/filter/filters/text.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dispatching/dispatchers/filter/filters/text.rs b/src/dispatching/dispatchers/filter/filters/text.rs index 2bb76a0e..c1d06c32 100644 --- a/src/dispatching/dispatchers/filter/filters/text.rs +++ b/src/dispatching/dispatchers/filter/filters/text.rs @@ -9,7 +9,12 @@ impl Filter<Message> for MessageTextFilter { fn test(&self, value: &Message) -> bool { match value.text() { Some(text) => self.text == text, - None => false + None => { + match value.caption() { + Some(caption) => self.text == caption, + None => false + } + } } } } From 720a34932f5e4b0be5139811280c6a73087189c1 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 18:36:37 +0300 Subject: [PATCH 59/66] divided TextFilter into MessageTextFilter and MessageCaptionFilter --- .../filter/filters/message_caption.rs | 98 +++++++++++++++++++ .../filters/{text.rs => message_text.rs} | 7 +- 2 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 src/dispatching/dispatchers/filter/filters/message_caption.rs rename src/dispatching/dispatchers/filter/filters/{text.rs => message_text.rs} (91%) diff --git a/src/dispatching/dispatchers/filter/filters/message_caption.rs b/src/dispatching/dispatchers/filter/filters/message_caption.rs new file mode 100644 index 00000000..d1c005ff --- /dev/null +++ b/src/dispatching/dispatchers/filter/filters/message_caption.rs @@ -0,0 +1,98 @@ +use crate::dispatching::Filter; +use crate::types::Message; + +pub struct MessageCaptionFilter { + text: String, +} + +impl Filter<Message> for MessageCaptionFilter { + fn test(&self, value: &Message) -> bool { + match value.caption() { + Some(caption) => self.text == caption, + None => false + } + } +} + +impl MessageCaptionFilter { + pub fn new(text: String) -> Self { + Self { + text + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn captions_are_equal() { + let filter = MessageCaptionFilter::new("caption".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "photo": [ + { + "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", + "file_size": 18188, + "width": 320, + "height": 239 + } + ], + "caption": "caption" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert!(filter.test(&message)); + } + + #[test] + fn captions_are_not_equal() { + let filter = MessageCaptionFilter::new("text".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "photo": [ + { + "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", + "file_size": 18188, + "width": 320, + "height": 239 + } + ], + "caption": "not equal caption" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert_eq!(filter.test(&message), false); + } +} \ No newline at end of file diff --git a/src/dispatching/dispatchers/filter/filters/text.rs b/src/dispatching/dispatchers/filter/filters/message_text.rs similarity index 91% rename from src/dispatching/dispatchers/filter/filters/text.rs rename to src/dispatching/dispatchers/filter/filters/message_text.rs index c1d06c32..2bb76a0e 100644 --- a/src/dispatching/dispatchers/filter/filters/text.rs +++ b/src/dispatching/dispatchers/filter/filters/message_text.rs @@ -9,12 +9,7 @@ impl Filter<Message> for MessageTextFilter { fn test(&self, value: &Message) -> bool { match value.text() { Some(text) => self.text == text, - None => { - match value.caption() { - Some(caption) => self.text == caption, - None => false - } - } + None => false } } } From f67011eb4299b3aefa3b597294b630efe972bed0 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 18:36:53 +0300 Subject: [PATCH 60/66] added CommandFilter --- .../dispatchers/filter/filters/command.rs | 147 ++++++++++++++++++ .../dispatchers/filter/filters/mod.rs | 8 +- 2 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 src/dispatching/dispatchers/filter/filters/command.rs diff --git a/src/dispatching/dispatchers/filter/filters/command.rs b/src/dispatching/dispatchers/filter/filters/command.rs new file mode 100644 index 00000000..07a81384 --- /dev/null +++ b/src/dispatching/dispatchers/filter/filters/command.rs @@ -0,0 +1,147 @@ +use crate::dispatching::Filter; +use crate::types::Message; +use std::ops::Add; + +struct CommandFilter { + command: String, +} + +impl Filter<Message> for CommandFilter { + fn test(&self, value: &Message) -> bool { + match value.text() { + Some(text) => { + match text.split_whitespace().next() { + Some(command) => self.command == command, + None => false + } + } + None => false + } + } +} + +impl CommandFilter { + pub fn new(command: String) -> Self { + Self { + command: '/'.to_string() + command.as_str() + } + } + pub fn with_start_string(command: String, start_string: String) -> Self { + Self { + command: start_string.add(command.as_str()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn commands_are_equal() { + let filter = CommandFilter::new("command".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "/command" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert!(filter.test(&message)); + } + + #[test] + fn commands_are_not_equal() { + let filter = CommandFilter::new("command".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "/command_not_equal" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert_eq!(filter.test(&message), false); + } + + #[test] + fn command_have_args() { + let filter = CommandFilter::new("command".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "/command arg1 arg2" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert!(filter.test(&message)); + } + + #[test] + fn message_have_only_whitespace() { + let filter = CommandFilter::new("command".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": " " + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert_eq!(filter.test(&message), false); + } +} diff --git a/src/dispatching/dispatchers/filter/filters/mod.rs b/src/dispatching/dispatchers/filter/filters/mod.rs index 45eaf476..4c0f0ae8 100644 --- a/src/dispatching/dispatchers/filter/filters/mod.rs +++ b/src/dispatching/dispatchers/filter/filters/mod.rs @@ -1,3 +1,7 @@ -pub use text::*; +pub use command::*; +pub use message_text::*; +pub use message_caption::*; -mod text; \ No newline at end of file +mod command; +mod message_text; +mod message_caption; \ No newline at end of file From e2cd5a8440c0cec5bf437deb46453a385ebc9f54 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 18:46:04 +0300 Subject: [PATCH 61/66] added generics into functions --- .../dispatchers/filter/filters/command.rs | 16 +++++++++++----- .../filter/filters/message_caption.rs | 7 +++++-- .../dispatchers/filter/filters/message_text.rs | 11 +++++++---- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/dispatching/dispatchers/filter/filters/command.rs b/src/dispatching/dispatchers/filter/filters/command.rs index 07a81384..fcb7fda4 100644 --- a/src/dispatching/dispatchers/filter/filters/command.rs +++ b/src/dispatching/dispatchers/filter/filters/command.rs @@ -2,7 +2,7 @@ use crate::dispatching::Filter; use crate::types::Message; use std::ops::Add; -struct CommandFilter { +pub struct CommandFilter { command: String, } @@ -21,14 +21,20 @@ impl Filter<Message> for CommandFilter { } impl CommandFilter { - pub fn new(command: String) -> Self { + pub fn new<T>(command: T) -> Self + where + T: Into<String>, + { Self { - command: '/'.to_string() + command.as_str() + command: '/'.to_string() + command.into().as_str() } } - pub fn with_start_string(command: String, start_string: String) -> Self { + pub fn with_start_string<T>(command: T, start_string: T) -> Self + where + T: Into<String>, + { Self { - command: start_string.add(command.as_str()) + command: start_string.into().add(command.into().as_str()) } } } diff --git a/src/dispatching/dispatchers/filter/filters/message_caption.rs b/src/dispatching/dispatchers/filter/filters/message_caption.rs index d1c005ff..f68d0837 100644 --- a/src/dispatching/dispatchers/filter/filters/message_caption.rs +++ b/src/dispatching/dispatchers/filter/filters/message_caption.rs @@ -15,9 +15,12 @@ impl Filter<Message> for MessageCaptionFilter { } impl MessageCaptionFilter { - pub fn new(text: String) -> Self { + pub fn new<T>(text: T) -> Self + where + T: Into<String>, + { Self { - text + text: text.into(), } } } diff --git a/src/dispatching/dispatchers/filter/filters/message_text.rs b/src/dispatching/dispatchers/filter/filters/message_text.rs index 2bb76a0e..765c149e 100644 --- a/src/dispatching/dispatchers/filter/filters/message_text.rs +++ b/src/dispatching/dispatchers/filter/filters/message_text.rs @@ -15,9 +15,12 @@ impl Filter<Message> for MessageTextFilter { } impl MessageTextFilter { - pub fn new(text: String) -> Self { + pub fn new<T>(text: T) -> Self + where + T: Into<String> + { Self { - text + text: text.into(), } } } @@ -28,7 +31,7 @@ mod tests { #[test] fn texts_are_equal() { - let filter = MessageTextFilter::new("text".to_string()); + let filter = MessageTextFilter::new("text"); let json = r#"{ "message_id": 199785, "from": { @@ -55,7 +58,7 @@ mod tests { #[test] fn texts_are_not_equal() { - let filter = MessageTextFilter::new("text".to_string()); + let filter = MessageTextFilter::new("text"); let json = r#"{ "message_id": 199785, "from": { From 053a946a341d7c4f90b1ea6b7ac4e4f77d1a67b2 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 19:21:48 +0300 Subject: [PATCH 62/66] added docs --- .../dispatchers/filter/filters/message_caption.rs | 13 +++++++++++++ .../dispatchers/filter/filters/message_text.rs | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/dispatching/dispatchers/filter/filters/message_caption.rs b/src/dispatching/dispatchers/filter/filters/message_caption.rs index f68d0837..ccb956f1 100644 --- a/src/dispatching/dispatchers/filter/filters/message_caption.rs +++ b/src/dispatching/dispatchers/filter/filters/message_caption.rs @@ -1,6 +1,19 @@ use crate::dispatching::Filter; use crate::types::Message; +/// Filter which compare caption of media with another text. +/// Returns true if the caption of media is equal to another text, otherwise false. +/// +/// NOTE: filter compares only caption of media, does not compare text of message! +/// +/// If you want to compare text of message use +/// [MessageTextFilter] +/// +/// If you want to compare text and caption use +/// [MessageTextCaptionFilter] +/// +/// [MessageTextFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextFilter +/// [MessageTextCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextCaptionFilter pub struct MessageCaptionFilter { text: String, } diff --git a/src/dispatching/dispatchers/filter/filters/message_text.rs b/src/dispatching/dispatchers/filter/filters/message_text.rs index 765c149e..01da11af 100644 --- a/src/dispatching/dispatchers/filter/filters/message_text.rs +++ b/src/dispatching/dispatchers/filter/filters/message_text.rs @@ -1,6 +1,19 @@ use crate::dispatching::Filter; use crate::types::Message; +/// Filter which compare message text with another text. +/// Returns true if the message text is equal to another text, otherwise false. +/// +/// NOTE: filter compares only text message, does not compare caption of media! +/// +/// If you want to compare caption use +/// [MessageCaptionFilter] +/// +/// If you want to compare text and caption use +/// [MessageTextCaptionFilter] +/// +/// [MessageCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageCaptionFilter +/// [MessageTextCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextCaptionFilter pub struct MessageTextFilter { text: String, } From 9feaf6336202060c4afb01cb9b423269948f952c Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Wed, 23 Oct 2019 19:28:01 +0300 Subject: [PATCH 63/66] added MessageTextCaptionFilter --- .../filter/filters/message_text_caption.rs | 173 ++++++++++++++++++ .../dispatchers/filter/filters/mod.rs | 4 +- 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/dispatching/dispatchers/filter/filters/message_text_caption.rs diff --git a/src/dispatching/dispatchers/filter/filters/message_text_caption.rs b/src/dispatching/dispatchers/filter/filters/message_text_caption.rs new file mode 100644 index 00000000..b56aeb28 --- /dev/null +++ b/src/dispatching/dispatchers/filter/filters/message_text_caption.rs @@ -0,0 +1,173 @@ +use crate::dispatching::Filter; +use crate::types::Message; + +/// Filter which compare message text or caption of media with another text. +/// Returns true if the message text or caption of media is equal to another text, otherwise false. +/// +/// NOTE: filter compares text of message or if it is not exists, compares caption of the message! +/// +/// If you want to compare only caption use +/// [MessageCaptionFilter] +/// +/// If you want to compare only text use +/// [MessageTextFilter] +/// +/// [MessageCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageCaptionFilter +/// [MessageTextFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextFilter +pub struct MessageTextCaptionFilter { + text: String, +} + +impl Filter<Message> for MessageTextCaptionFilter { + fn test(&self, value: &Message) -> bool { + match value.text() { + Some(text) => self.text == text, + None => { + match value.caption() { + Some(caption) => self.text == caption, + None => false + } + } + } + } +} + +impl MessageTextCaptionFilter { + pub fn new<T>(text: T) -> Self + where + T: Into<String> + { + Self { + text: text.into(), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn texts_are_equal() { + let filter = MessageTextCaptionFilter::new("text"); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "text" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert!(filter.test(&message)); + } + + #[test] + fn texts_are_not_equal() { + let filter = MessageTextCaptionFilter::new("text"); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "text": "not equal text" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert_eq!(filter.test(&message), false); + } + + #[test] + fn captions_are_equal() { + let filter = MessageTextCaptionFilter::new("caption".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "photo": [ + { + "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", + "file_size": 18188, + "width": 320, + "height": 239 + } + ], + "caption": "caption" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert!(filter.test(&message)); + } + + #[test] + fn captions_are_not_equal() { + let filter = MessageTextCaptionFilter::new("text".to_string()); + let json = r#"{ + "message_id": 199785, + "from": { + "id": 250918540, + "is_bot": false, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "language_code": "en" + }, + "chat": { + "id": 250918540, + "first_name": "Андрей", + "last_name": "Власов", + "username": "aka_dude", + "type": "private" + }, + "date": 1568289890, + "photo": [ + { + "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", + "file_size": 18188, + "width": 320, + "height": 239 + } + ], + "caption": "not equal caption" + }"#; + let message = serde_json::from_str::<Message>(json).unwrap(); + assert_eq!(filter.test(&message), false); + } +} \ No newline at end of file diff --git a/src/dispatching/dispatchers/filter/filters/mod.rs b/src/dispatching/dispatchers/filter/filters/mod.rs index 4c0f0ae8..e54376eb 100644 --- a/src/dispatching/dispatchers/filter/filters/mod.rs +++ b/src/dispatching/dispatchers/filter/filters/mod.rs @@ -1,7 +1,9 @@ pub use command::*; pub use message_text::*; pub use message_caption::*; +pub use message_text_caption::*; mod command; mod message_text; -mod message_caption; \ No newline at end of file +mod message_caption; +mod message_text_caption; \ No newline at end of file From 0add325e3188a79b05ded10bdae849d57c1b9371 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Fri, 25 Oct 2019 18:09:56 +0300 Subject: [PATCH 64/66] optimized tests --- .../dispatchers/filter/filters/command.rs | 132 +++++-------- .../filter/filters/message_caption.rs | 101 ++++------ .../filter/filters/message_text.rs | 81 ++++---- .../filter/filters/message_text_caption.rs | 181 ++++++++---------- 4 files changed, 205 insertions(+), 290 deletions(-) diff --git a/src/dispatching/dispatchers/filter/filters/command.rs b/src/dispatching/dispatchers/filter/filters/command.rs index fcb7fda4..0588330c 100644 --- a/src/dispatching/dispatchers/filter/filters/command.rs +++ b/src/dispatching/dispatchers/filter/filters/command.rs @@ -1,6 +1,5 @@ use crate::dispatching::Filter; use crate::types::Message; -use std::ops::Add; pub struct CommandFilter { command: String, @@ -26,15 +25,15 @@ impl CommandFilter { T: Into<String>, { Self { - command: '/'.to_string() + command.into().as_str() + command: '/'.to_string() + &command.into() } } - pub fn with_start_string<T>(command: T, start_string: T) -> Self + pub fn with_prefix<T>(command: T, prefix: T) -> Self where T: Into<String>, { Self { - command: start_string.into().add(command.into().as_str()) + command: prefix.into() + &command.into() } } } @@ -42,112 +41,69 @@ impl CommandFilter { #[cfg(test)] mod tests { use super::*; + use crate::types::{Chat, ChatKind, MessageKind, Sender, User, ForwardKind, MediaKind}; #[test] fn commands_are_equal() { let filter = CommandFilter::new("command".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "/command" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("/command".to_string()); assert!(filter.test(&message)); } #[test] fn commands_are_not_equal() { let filter = CommandFilter::new("command".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "/command_not_equal" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("/not_equal_command".to_string()); assert_eq!(filter.test(&message), false); } #[test] fn command_have_args() { let filter = CommandFilter::new("command".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "/command arg1 arg2" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("/command arg1 arg2".to_string()); assert!(filter.test(&message)); } #[test] fn message_have_only_whitespace() { let filter = CommandFilter::new("command".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": " " - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text(" ".to_string()); assert_eq!(filter.test(&message), false); } + + fn create_message_with_text(text: String) -> Message { + Message { + id: 0, + date: 0, + chat: Chat { + id: 0, + kind: ChatKind::Private { + type_: (), + username: None, + first_name: None, + last_name: None + }, + photo: None + }, + kind: MessageKind::Common { + from: Sender::User(User { + id: 0, + is_bot: false, + first_name: "".to_string(), + last_name: None, + username: None, + language_code: None + }), + forward_kind: ForwardKind::Origin { + reply_to_message: None + }, + edit_date: None, + media_kind: MediaKind::Text { + text, + entities: vec![] + }, + reply_markup: None + } + } + } } diff --git a/src/dispatching/dispatchers/filter/filters/message_caption.rs b/src/dispatching/dispatchers/filter/filters/message_caption.rs index ccb956f1..aed705c8 100644 --- a/src/dispatching/dispatchers/filter/filters/message_caption.rs +++ b/src/dispatching/dispatchers/filter/filters/message_caption.rs @@ -41,74 +41,57 @@ impl MessageCaptionFilter { #[cfg(test)] mod tests { use super::*; + use crate::types::{Chat, Sender, ChatKind, MessageKind, ForwardKind, User, MediaKind}; #[test] fn captions_are_equal() { let filter = MessageCaptionFilter::new("caption".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "photo": [ - { - "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", - "file_size": 18188, - "width": 320, - "height": 239 - } - ], - "caption": "caption" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_caption("caption".to_string()); assert!(filter.test(&message)); } #[test] fn captions_are_not_equal() { - let filter = MessageCaptionFilter::new("text".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "photo": [ - { - "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", - "file_size": 18188, - "width": 320, - "height": 239 - } - ], - "caption": "not equal caption" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let filter = MessageCaptionFilter::new("caption".to_string()); + let message = create_message_with_caption("not equal caption".to_string()); assert_eq!(filter.test(&message), false); } + + fn create_message_with_caption(caption: String) -> Message { + Message { + id: 0, + date: 0, + chat: Chat { + id: 0, + kind: ChatKind::Private { + type_: (), + username: None, + first_name: None, + last_name: None + }, + photo: None + }, + kind: MessageKind::Common { + from: Sender::User(User { + id: 0, + is_bot: false, + first_name: "".to_string(), + last_name: None, + username: None, + language_code: None + }), + forward_kind: ForwardKind::Origin { + reply_to_message: None + }, + edit_date: None, + media_kind: MediaKind::Photo { + photo: vec![], + caption: Some(caption), + caption_entities: vec![], + media_group_id: None + }, + reply_markup: None + } + } + } } \ No newline at end of file diff --git a/src/dispatching/dispatchers/filter/filters/message_text.rs b/src/dispatching/dispatchers/filter/filters/message_text.rs index 01da11af..3af158ea 100644 --- a/src/dispatching/dispatchers/filter/filters/message_text.rs +++ b/src/dispatching/dispatchers/filter/filters/message_text.rs @@ -41,58 +41,55 @@ impl MessageTextFilter { #[cfg(test)] mod tests { use super::*; + use crate::types::{Chat, Sender, ChatKind, MessageKind, ForwardKind, User, MediaKind}; #[test] fn texts_are_equal() { let filter = MessageTextFilter::new("text"); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "text" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("text".to_string()); assert!(filter.test(&message)); } #[test] fn texts_are_not_equal() { let filter = MessageTextFilter::new("text"); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "not equal text" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("not equal text".to_string()); assert_eq!(filter.test(&message), false); } + + fn create_message_with_text(text: String) -> Message { + Message { + id: 0, + date: 0, + chat: Chat { + id: 0, + kind: ChatKind::Private { + type_: (), + username: None, + first_name: None, + last_name: None + }, + photo: None + }, + kind: MessageKind::Common { + from: Sender::User(User { + id: 0, + is_bot: false, + first_name: "".to_string(), + last_name: None, + username: None, + language_code: None + }), + forward_kind: ForwardKind::Origin { + reply_to_message: None + }, + edit_date: None, + media_kind: MediaKind::Text { + text, + entities: vec![] + }, + reply_markup: None + } + } + } } \ No newline at end of file diff --git a/src/dispatching/dispatchers/filter/filters/message_text_caption.rs b/src/dispatching/dispatchers/filter/filters/message_text_caption.rs index b56aeb28..193d13e1 100644 --- a/src/dispatching/dispatchers/filter/filters/message_text_caption.rs +++ b/src/dispatching/dispatchers/filter/filters/message_text_caption.rs @@ -46,128 +46,107 @@ impl MessageTextCaptionFilter { #[cfg(test)] mod tests { use super::*; + use crate::types::{Chat, Sender, ChatKind, MessageKind, ForwardKind, User, MediaKind}; #[test] fn texts_are_equal() { let filter = MessageTextCaptionFilter::new("text"); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "text" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("text".to_string()); assert!(filter.test(&message)); } #[test] fn texts_are_not_equal() { let filter = MessageTextCaptionFilter::new("text"); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "text": "not equal text" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_text("not equal text".to_string()); assert_eq!(filter.test(&message), false); } + fn create_message_with_text(text: String) -> Message { + Message { + id: 0, + date: 0, + chat: Chat { + id: 0, + kind: ChatKind::Private { + type_: (), + username: None, + first_name: None, + last_name: None + }, + photo: None + }, + kind: MessageKind::Common { + from: Sender::User(User { + id: 0, + is_bot: false, + first_name: "".to_string(), + last_name: None, + username: None, + language_code: None + }), + forward_kind: ForwardKind::Origin { + reply_to_message: None + }, + edit_date: None, + media_kind: MediaKind::Text { + text, + entities: vec![] + }, + reply_markup: None + } + } + } + #[test] fn captions_are_equal() { let filter = MessageTextCaptionFilter::new("caption".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "photo": [ - { - "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", - "file_size": 18188, - "width": 320, - "height": 239 - } - ], - "caption": "caption" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let message = create_message_with_caption("caption".to_string()); assert!(filter.test(&message)); } #[test] fn captions_are_not_equal() { - let filter = MessageTextCaptionFilter::new("text".to_string()); - let json = r#"{ - "message_id": 199785, - "from": { - "id": 250918540, - "is_bot": false, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "language_code": "en" - }, - "chat": { - "id": 250918540, - "first_name": "Андрей", - "last_name": "Власов", - "username": "aka_dude", - "type": "private" - }, - "date": 1568289890, - "photo": [ - { - "file_id": "AgADAgAD36sxG-PX0UvQSXIn9rccdw-ACA4ABAEAAwIAA20AAybcBAABFgQ", - "file_size": 18188, - "width": 320, - "height": 239 - } - ], - "caption": "not equal caption" - }"#; - let message = serde_json::from_str::<Message>(json).unwrap(); + let filter = MessageTextCaptionFilter::new("caption".to_string()); + let message = create_message_with_caption("not equal caption".to_string()); assert_eq!(filter.test(&message), false); } + + fn create_message_with_caption(caption: String) -> Message { + Message { + id: 0, + date: 0, + chat: Chat { + id: 0, + kind: ChatKind::Private { + type_: (), + username: None, + first_name: None, + last_name: None + }, + photo: None + }, + kind: MessageKind::Common { + from: Sender::User(User { + id: 0, + is_bot: false, + first_name: "".to_string(), + last_name: None, + username: None, + language_code: None + }), + forward_kind: ForwardKind::Origin { + reply_to_message: None + }, + edit_date: None, + media_kind: MediaKind::Photo { + photo: vec![], + caption: Some(caption), + caption_entities: vec![], + media_group_id: None + }, + reply_markup: None + } + } + } } \ No newline at end of file From 262031cd812ee5048eec9ce2c274b4393f351be6 Mon Sep 17 00:00:00 2001 From: P0lunin <polunindima2002@gmail.com> Date: Fri, 25 Oct 2019 18:16:10 +0300 Subject: [PATCH 65/66] moved filters from ..\dispatching\dispatchers\filter\ to ..\dispatching\ --- src/dispatching/dispatchers/filter/mod.rs | 1 - .../filter => }/filters/command.rs | 0 .../{filters.rs => filters/main.rs} | 32 +++++++++---------- .../filter => }/filters/message_caption.rs | 4 +-- .../filter => }/filters/message_text.rs | 4 +-- .../filters/message_text_caption.rs | 4 +-- .../{dispatchers/filter => }/filters/mod.rs | 4 +++ 7 files changed, 26 insertions(+), 23 deletions(-) rename src/dispatching/{dispatchers/filter => }/filters/command.rs (100%) rename src/dispatching/{filters.rs => filters/main.rs} (97%) rename src/dispatching/{dispatchers/filter => }/filters/message_caption.rs (92%) rename src/dispatching/{dispatchers/filter => }/filters/message_text.rs (92%) rename src/dispatching/{dispatchers/filter => }/filters/message_text_caption.rs (95%) rename src/dispatching/{dispatchers/filter => }/filters/mod.rs (86%) diff --git a/src/dispatching/dispatchers/filter/mod.rs b/src/dispatching/dispatchers/filter/mod.rs index 816867fc..b3ed259f 100644 --- a/src/dispatching/dispatchers/filter/mod.rs +++ b/src/dispatching/dispatchers/filter/mod.rs @@ -10,7 +10,6 @@ use crate::{ types::{CallbackQuery, ChosenInlineResult, Message, Update, UpdateKind}, }; -pub mod filters; pub mod error_policy; type Handlers<'a, T, E> = diff --git a/src/dispatching/dispatchers/filter/filters/command.rs b/src/dispatching/filters/command.rs similarity index 100% rename from src/dispatching/dispatchers/filter/filters/command.rs rename to src/dispatching/filters/command.rs diff --git a/src/dispatching/filters.rs b/src/dispatching/filters/main.rs similarity index 97% rename from src/dispatching/filters.rs rename to src/dispatching/filters/main.rs index 8c513405..6b3f3c3d 100644 --- a/src/dispatching/filters.rs +++ b/src/dispatching/filters/main.rs @@ -60,9 +60,9 @@ impl<A, B> And<A, B> { } impl<T, A, B> Filter<T> for And<A, B> -where - A: Filter<T>, - B: Filter<T>, + where + A: Filter<T>, + B: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) && self.1.test(value) @@ -111,9 +111,9 @@ impl<A, B> Or<A, B> { } impl<T, A, B> Filter<T> for Or<A, B> -where - A: Filter<T>, - B: Filter<T>, + where + A: Filter<T>, + B: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) || self.1.test(value) @@ -157,8 +157,8 @@ impl<A> Not<A> { } impl<T, A> Filter<T> for Not<A> -where - A: Filter<T>, + where + A: Filter<T>, { fn test(&self, value: &T) -> bool { !self.0.test(value) @@ -283,8 +283,8 @@ pub fn f<A>(a: A) -> F<A> { } impl<T, A> Filter<T> for F<A> -where - A: Filter<T>, + where + A: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) @@ -324,8 +324,8 @@ pub trait FilterExt<T> { /// /// [`Not::new`]: crate::dispatching::filter::Not::new fn not(self) -> Not<Self> - where - Self: Sized, + where + Self: Sized, { Not::new(self) } @@ -346,8 +346,8 @@ pub trait FilterExt<T> { /// /// [`Not::new`]: crate::dispatching::filter::And::new fn and<B>(self, other: B) -> And<Self, B> - where - Self: Sized, + where + Self: Sized, { And::new(self, other) } @@ -368,8 +368,8 @@ pub trait FilterExt<T> { /// /// [`Not::new`]: crate::dispatching::filter::Or::new fn or<B>(self, other: B) -> Or<Self, B> - where - Self: Sized, + where + Self: Sized, { Or::new(self, other) } diff --git a/src/dispatching/dispatchers/filter/filters/message_caption.rs b/src/dispatching/filters/message_caption.rs similarity index 92% rename from src/dispatching/dispatchers/filter/filters/message_caption.rs rename to src/dispatching/filters/message_caption.rs index aed705c8..a940d49f 100644 --- a/src/dispatching/dispatchers/filter/filters/message_caption.rs +++ b/src/dispatching/filters/message_caption.rs @@ -12,8 +12,8 @@ use crate::types::Message; /// If you want to compare text and caption use /// [MessageTextCaptionFilter] /// -/// [MessageTextFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextFilter -/// [MessageTextCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextCaptionFilter +/// [MessageTextFilter]: telebofr::dispatching::filters::MessageTextFilter +/// [MessageTextCaptionFilter]: telebofr::dispatching::filters::MessageTextCaptionFilter pub struct MessageCaptionFilter { text: String, } diff --git a/src/dispatching/dispatchers/filter/filters/message_text.rs b/src/dispatching/filters/message_text.rs similarity index 92% rename from src/dispatching/dispatchers/filter/filters/message_text.rs rename to src/dispatching/filters/message_text.rs index 3af158ea..e5079823 100644 --- a/src/dispatching/dispatchers/filter/filters/message_text.rs +++ b/src/dispatching/filters/message_text.rs @@ -12,8 +12,8 @@ use crate::types::Message; /// If you want to compare text and caption use /// [MessageTextCaptionFilter] /// -/// [MessageCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageCaptionFilter -/// [MessageTextCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextCaptionFilter +/// [MessageCaptionFilter]: telebofr::dispatching::filters::MessageCaptionFilter +/// [MessageTextCaptionFilter]: telebofr::dispatching::filters::MessageTextCaptionFilter pub struct MessageTextFilter { text: String, } diff --git a/src/dispatching/dispatchers/filter/filters/message_text_caption.rs b/src/dispatching/filters/message_text_caption.rs similarity index 95% rename from src/dispatching/dispatchers/filter/filters/message_text_caption.rs rename to src/dispatching/filters/message_text_caption.rs index 193d13e1..bc144c27 100644 --- a/src/dispatching/dispatchers/filter/filters/message_text_caption.rs +++ b/src/dispatching/filters/message_text_caption.rs @@ -12,8 +12,8 @@ use crate::types::Message; /// If you want to compare only text use /// [MessageTextFilter] /// -/// [MessageCaptionFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageCaptionFilter -/// [MessageTextFilter]: telebofr::dispatching::dispatchers::filter::filters::MessageTextFilter +/// [MessageCaptionFilter]: telebofr::dispatching::filters::MessageCaptionFilter +/// [MessageTextFilter]: telebofr::filter::filters::MessageTextFilter pub struct MessageTextCaptionFilter { text: String, } diff --git a/src/dispatching/dispatchers/filter/filters/mod.rs b/src/dispatching/filters/mod.rs similarity index 86% rename from src/dispatching/dispatchers/filter/filters/mod.rs rename to src/dispatching/filters/mod.rs index e54376eb..6d4b47ef 100644 --- a/src/dispatching/dispatchers/filter/filters/mod.rs +++ b/src/dispatching/filters/mod.rs @@ -1,8 +1,12 @@ +pub use main::*; + pub use command::*; pub use message_text::*; pub use message_caption::*; pub use message_text_caption::*; +mod main; + mod command; mod message_text; mod message_caption; From 04dd861f5161cadb18179b6272fecaa72bb96cd9 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi <gymmasssorla@gmail.com> Date: Tue, 29 Oct 2019 01:28:38 +0600 Subject: [PATCH 66/66] Fmt --- src/bot/download.rs | 6 +- src/dispatching/filters/command.rs | 43 +++++++------ src/dispatching/filters/main.rs | 32 +++++----- src/dispatching/filters/message_caption.rs | 41 ++++++------ src/dispatching/filters/message_text.rs | 34 +++++----- .../filters/message_text_caption.rs | 64 +++++++++---------- src/dispatching/filters/mod.rs | 6 +- 7 files changed, 115 insertions(+), 111 deletions(-) diff --git a/src/bot/download.rs b/src/bot/download.rs index b768f43d..abb2da78 100644 --- a/src/bot/download.rs +++ b/src/bot/download.rs @@ -8,7 +8,7 @@ use crate::network::download_file_stream; use crate::{bot::Bot, network::download_file, DownloadError}; impl Bot { - /// Download file from telegram into `destination`. + /// Download a file from Telegram into `destination`. /// `path` can be obtained from [`get_file`] method. /// /// For downloading as Stream of Chunks see [`download_file_stream`]. @@ -43,9 +43,9 @@ impl Bot { download_file(&self.client, &self.token, path, destination).await } - /// Download file from telegram. + /// Download a file from Telegram. /// - /// `path` can be obtained from [`get_file`] method. + /// `path` can be obtained from the [`get_file`] method. /// /// For downloading into [`AsyncWrite`] (e.g. [`tokio::fs::File`]) /// see [`download_file`]. diff --git a/src/dispatching/filters/command.rs b/src/dispatching/filters/command.rs index 0588330c..b807050a 100644 --- a/src/dispatching/filters/command.rs +++ b/src/dispatching/filters/command.rs @@ -1,5 +1,4 @@ -use crate::dispatching::Filter; -use crate::types::Message; +use crate::{dispatching::Filter, types::Message}; pub struct CommandFilter { command: String, @@ -8,13 +7,11 @@ pub struct CommandFilter { impl Filter<Message> for CommandFilter { fn test(&self, value: &Message) -> bool { match value.text() { - Some(text) => { - match text.split_whitespace().next() { - Some(command) => self.command == command, - None => false - } - } - None => false + Some(text) => match text.split_whitespace().next() { + Some(command) => self.command == command, + None => false, + }, + None => false, } } } @@ -25,7 +22,7 @@ impl CommandFilter { T: Into<String>, { Self { - command: '/'.to_string() + &command.into() + command: '/'.to_string() + &command.into(), } } pub fn with_prefix<T>(command: T, prefix: T) -> Self @@ -33,7 +30,7 @@ impl CommandFilter { T: Into<String>, { Self { - command: prefix.into() + &command.into() + command: prefix.into() + &command.into(), } } } @@ -41,7 +38,9 @@ impl CommandFilter { #[cfg(test)] mod tests { use super::*; - use crate::types::{Chat, ChatKind, MessageKind, Sender, User, ForwardKind, MediaKind}; + use crate::types::{ + Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User, + }; #[test] fn commands_are_equal() { @@ -53,14 +52,16 @@ mod tests { #[test] fn commands_are_not_equal() { let filter = CommandFilter::new("command".to_string()); - let message = create_message_with_text("/not_equal_command".to_string()); + let message = + create_message_with_text("/not_equal_command".to_string()); assert_eq!(filter.test(&message), false); } #[test] fn command_have_args() { let filter = CommandFilter::new("command".to_string()); - let message = create_message_with_text("/command arg1 arg2".to_string()); + let message = + create_message_with_text("/command arg1 arg2".to_string()); assert!(filter.test(&message)); } @@ -81,9 +82,9 @@ mod tests { type_: (), username: None, first_name: None, - last_name: None + last_name: None, }, - photo: None + photo: None, }, kind: MessageKind::Common { from: Sender::User(User { @@ -92,18 +93,18 @@ mod tests { first_name: "".to_string(), last_name: None, username: None, - language_code: None + language_code: None, }), forward_kind: ForwardKind::Origin { - reply_to_message: None + reply_to_message: None, }, edit_date: None, media_kind: MediaKind::Text { text, - entities: vec![] + entities: vec![], }, - reply_markup: None - } + reply_markup: None, + }, } } } diff --git a/src/dispatching/filters/main.rs b/src/dispatching/filters/main.rs index 6b3f3c3d..8c513405 100644 --- a/src/dispatching/filters/main.rs +++ b/src/dispatching/filters/main.rs @@ -60,9 +60,9 @@ impl<A, B> And<A, B> { } impl<T, A, B> Filter<T> for And<A, B> - where - A: Filter<T>, - B: Filter<T>, +where + A: Filter<T>, + B: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) && self.1.test(value) @@ -111,9 +111,9 @@ impl<A, B> Or<A, B> { } impl<T, A, B> Filter<T> for Or<A, B> - where - A: Filter<T>, - B: Filter<T>, +where + A: Filter<T>, + B: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) || self.1.test(value) @@ -157,8 +157,8 @@ impl<A> Not<A> { } impl<T, A> Filter<T> for Not<A> - where - A: Filter<T>, +where + A: Filter<T>, { fn test(&self, value: &T) -> bool { !self.0.test(value) @@ -283,8 +283,8 @@ pub fn f<A>(a: A) -> F<A> { } impl<T, A> Filter<T> for F<A> - where - A: Filter<T>, +where + A: Filter<T>, { fn test(&self, value: &T) -> bool { self.0.test(value) @@ -324,8 +324,8 @@ pub trait FilterExt<T> { /// /// [`Not::new`]: crate::dispatching::filter::Not::new fn not(self) -> Not<Self> - where - Self: Sized, + where + Self: Sized, { Not::new(self) } @@ -346,8 +346,8 @@ pub trait FilterExt<T> { /// /// [`Not::new`]: crate::dispatching::filter::And::new fn and<B>(self, other: B) -> And<Self, B> - where - Self: Sized, + where + Self: Sized, { And::new(self, other) } @@ -368,8 +368,8 @@ pub trait FilterExt<T> { /// /// [`Not::new`]: crate::dispatching::filter::Or::new fn or<B>(self, other: B) -> Or<Self, B> - where - Self: Sized, + where + Self: Sized, { Or::new(self, other) } diff --git a/src/dispatching/filters/message_caption.rs b/src/dispatching/filters/message_caption.rs index a940d49f..0539390e 100644 --- a/src/dispatching/filters/message_caption.rs +++ b/src/dispatching/filters/message_caption.rs @@ -1,10 +1,11 @@ -use crate::dispatching::Filter; -use crate::types::Message; +use crate::{dispatching::Filter, types::Message}; /// Filter which compare caption of media with another text. -/// Returns true if the caption of media is equal to another text, otherwise false. +/// Returns true if the caption of media is equal to another text, otherwise +/// false. /// -/// NOTE: filter compares only caption of media, does not compare text of message! +/// NOTE: filter compares only caption of media, does not compare text of +/// message! /// /// If you want to compare text of message use /// [MessageTextFilter] @@ -13,7 +14,8 @@ use crate::types::Message; /// [MessageTextCaptionFilter] /// /// [MessageTextFilter]: telebofr::dispatching::filters::MessageTextFilter -/// [MessageTextCaptionFilter]: telebofr::dispatching::filters::MessageTextCaptionFilter +/// [MessageTextCaptionFilter]: +/// telebofr::dispatching::filters::MessageTextCaptionFilter pub struct MessageCaptionFilter { text: String, } @@ -22,7 +24,7 @@ impl Filter<Message> for MessageCaptionFilter { fn test(&self, value: &Message) -> bool { match value.caption() { Some(caption) => self.text == caption, - None => false + None => false, } } } @@ -32,16 +34,16 @@ impl MessageCaptionFilter { where T: Into<String>, { - Self { - text: text.into(), - } + Self { text: text.into() } } } #[cfg(test)] mod tests { use super::*; - use crate::types::{Chat, Sender, ChatKind, MessageKind, ForwardKind, User, MediaKind}; + use crate::types::{ + Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User, + }; #[test] fn captions_are_equal() { @@ -53,7 +55,8 @@ mod tests { #[test] fn captions_are_not_equal() { let filter = MessageCaptionFilter::new("caption".to_string()); - let message = create_message_with_caption("not equal caption".to_string()); + let message = + create_message_with_caption("not equal caption".to_string()); assert_eq!(filter.test(&message), false); } @@ -67,9 +70,9 @@ mod tests { type_: (), username: None, first_name: None, - last_name: None + last_name: None, }, - photo: None + photo: None, }, kind: MessageKind::Common { from: Sender::User(User { @@ -78,20 +81,20 @@ mod tests { first_name: "".to_string(), last_name: None, username: None, - language_code: None + language_code: None, }), forward_kind: ForwardKind::Origin { - reply_to_message: None + reply_to_message: None, }, edit_date: None, media_kind: MediaKind::Photo { photo: vec![], caption: Some(caption), caption_entities: vec![], - media_group_id: None + media_group_id: None, }, - reply_markup: None - } + reply_markup: None, + }, } } -} \ No newline at end of file +} diff --git a/src/dispatching/filters/message_text.rs b/src/dispatching/filters/message_text.rs index e5079823..28db8206 100644 --- a/src/dispatching/filters/message_text.rs +++ b/src/dispatching/filters/message_text.rs @@ -1,5 +1,4 @@ -use crate::dispatching::Filter; -use crate::types::Message; +use crate::{dispatching::Filter, types::Message}; /// Filter which compare message text with another text. /// Returns true if the message text is equal to another text, otherwise false. @@ -13,7 +12,8 @@ use crate::types::Message; /// [MessageTextCaptionFilter] /// /// [MessageCaptionFilter]: telebofr::dispatching::filters::MessageCaptionFilter -/// [MessageTextCaptionFilter]: telebofr::dispatching::filters::MessageTextCaptionFilter +/// [MessageTextCaptionFilter]: +/// telebofr::dispatching::filters::MessageTextCaptionFilter pub struct MessageTextFilter { text: String, } @@ -22,7 +22,7 @@ impl Filter<Message> for MessageTextFilter { fn test(&self, value: &Message) -> bool { match value.text() { Some(text) => self.text == text, - None => false + None => false, } } } @@ -30,18 +30,18 @@ impl Filter<Message> for MessageTextFilter { impl MessageTextFilter { pub fn new<T>(text: T) -> Self where - T: Into<String> + T: Into<String>, { - Self { - text: text.into(), - } + Self { text: text.into() } } } #[cfg(test)] mod tests { use super::*; - use crate::types::{Chat, Sender, ChatKind, MessageKind, ForwardKind, User, MediaKind}; + use crate::types::{ + Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User, + }; #[test] fn texts_are_equal() { @@ -67,9 +67,9 @@ mod tests { type_: (), username: None, first_name: None, - last_name: None + last_name: None, }, - photo: None + photo: None, }, kind: MessageKind::Common { from: Sender::User(User { @@ -78,18 +78,18 @@ mod tests { first_name: "".to_string(), last_name: None, username: None, - language_code: None + language_code: None, }), forward_kind: ForwardKind::Origin { - reply_to_message: None + reply_to_message: None, }, edit_date: None, media_kind: MediaKind::Text { text, - entities: vec![] + entities: vec![], }, - reply_markup: None - } + reply_markup: None, + }, } } -} \ No newline at end of file +} diff --git a/src/dispatching/filters/message_text_caption.rs b/src/dispatching/filters/message_text_caption.rs index bc144c27..5ee0df1f 100644 --- a/src/dispatching/filters/message_text_caption.rs +++ b/src/dispatching/filters/message_text_caption.rs @@ -1,10 +1,11 @@ -use crate::dispatching::Filter; -use crate::types::Message; +use crate::{dispatching::Filter, types::Message}; /// Filter which compare message text or caption of media with another text. -/// Returns true if the message text or caption of media is equal to another text, otherwise false. +/// Returns true if the message text or caption of media is equal to another +/// text, otherwise false. /// -/// NOTE: filter compares text of message or if it is not exists, compares caption of the message! +/// NOTE: filter compares text of message or if it is not exists, compares +/// caption of the message! /// /// If you want to compare only caption use /// [MessageCaptionFilter] @@ -22,31 +23,29 @@ impl Filter<Message> for MessageTextCaptionFilter { fn test(&self, value: &Message) -> bool { match value.text() { Some(text) => self.text == text, - None => { - match value.caption() { - Some(caption) => self.text == caption, - None => false - } - } + None => match value.caption() { + Some(caption) => self.text == caption, + None => false, + }, } } } impl MessageTextCaptionFilter { pub fn new<T>(text: T) -> Self - where - T: Into<String> + where + T: Into<String>, { - Self { - text: text.into(), - } + Self { text: text.into() } } } #[cfg(test)] mod tests { use super::*; - use crate::types::{Chat, Sender, ChatKind, MessageKind, ForwardKind, User, MediaKind}; + use crate::types::{ + Chat, ChatKind, ForwardKind, MediaKind, MessageKind, Sender, User, + }; #[test] fn texts_are_equal() { @@ -72,9 +71,9 @@ mod tests { type_: (), username: None, first_name: None, - last_name: None + last_name: None, }, - photo: None + photo: None, }, kind: MessageKind::Common { from: Sender::User(User { @@ -83,18 +82,18 @@ mod tests { first_name: "".to_string(), last_name: None, username: None, - language_code: None + language_code: None, }), forward_kind: ForwardKind::Origin { - reply_to_message: None + reply_to_message: None, }, edit_date: None, media_kind: MediaKind::Text { text, - entities: vec![] + entities: vec![], }, - reply_markup: None - } + reply_markup: None, + }, } } @@ -108,7 +107,8 @@ mod tests { #[test] fn captions_are_not_equal() { let filter = MessageTextCaptionFilter::new("caption".to_string()); - let message = create_message_with_caption("not equal caption".to_string()); + let message = + create_message_with_caption("not equal caption".to_string()); assert_eq!(filter.test(&message), false); } @@ -122,9 +122,9 @@ mod tests { type_: (), username: None, first_name: None, - last_name: None + last_name: None, }, - photo: None + photo: None, }, kind: MessageKind::Common { from: Sender::User(User { @@ -133,20 +133,20 @@ mod tests { first_name: "".to_string(), last_name: None, username: None, - language_code: None + language_code: None, }), forward_kind: ForwardKind::Origin { - reply_to_message: None + reply_to_message: None, }, edit_date: None, media_kind: MediaKind::Photo { photo: vec![], caption: Some(caption), caption_entities: vec![], - media_group_id: None + media_group_id: None, }, - reply_markup: None - } + reply_markup: None, + }, } } -} \ No newline at end of file +} diff --git a/src/dispatching/filters/mod.rs b/src/dispatching/filters/mod.rs index 6d4b47ef..b3f9237f 100644 --- a/src/dispatching/filters/mod.rs +++ b/src/dispatching/filters/mod.rs @@ -1,13 +1,13 @@ pub use main::*; pub use command::*; -pub use message_text::*; pub use message_caption::*; +pub use message_text::*; pub use message_text_caption::*; mod main; mod command; -mod message_text; mod message_caption; -mod message_text_caption; \ No newline at end of file +mod message_text; +mod message_text_caption;