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_n&#5z24r`_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;