diff --git a/src/core/mod.rs b/src/core/mod.rs index cd8bb2d5..8fd20ac7 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -1,3 +1,3 @@ -pub mod network; +mod network; pub mod requests; pub mod types; diff --git a/src/core/network/mod.rs b/src/core/network/mod.rs index c1d5eba0..da42bd36 100644 --- a/src/core/network/mod.rs +++ b/src/core/network/mod.rs @@ -1,17 +1,16 @@ +use apply::Apply; use futures::compat::Future01CompatExt; +use reqwest::r#async::{multipart::Form, Client}; use serde::de::DeserializeOwned; use serde_json::Value; -use reqwest::{ - r#async::{Client, multipart::Form}, - StatusCode, -}; -use apply::Apply; +use crate::core::requests::{RequestError, ResponseResult}; const TELEGRAM_API_URL: &str = "https://api.telegram.org"; - -/// Create url for macking requests, see [telegram docs](https://core.telegram.org/bots/api#making-requests) +/// Creates URL for making HTTPS requests. See the [Telegram documentation]. +/// +/// [Telegram documentation]: https://core.telegram.org/bots/api#making-requests fn method_url(base: &str, token: &str, method_name: &str) -> String { format!( "{url}/bot{token}/{method}", @@ -21,7 +20,9 @@ fn method_url(base: &str, token: &str, method_name: &str) -> String { ) } -/// Create url for downloading file, see [telegram docs](https://core.telegram.org/bots/api#file) +/// Creates URL for downloading a file. See the [Telegram documentation]. +/// +/// [Telegram documentation] (https://core.telegram.org/bots/api#file) fn file_url(base: &str, token: &str, file_path: &str) -> String { format!( "{url}/file/bot{token}/{file}", @@ -31,33 +32,6 @@ fn file_url(base: &str, token: &str, file_path: &str) -> String { ) } -#[derive(Debug, Display)] -pub enum RequestError { - #[display(fmt = "Telegram error #{}: {}", status_code, description)] - ApiError { - status_code: StatusCode, - description: String, - }, - - #[display(fmt = "Network error: {err}", err = _0)] - NetworkError(reqwest::Error), - - #[display(fmt = "InvalidJson error caused by: {err}", err = _0)] - InvalidJson(serde_json::Error), -} - -impl std::error::Error for RequestError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match self { - RequestError::ApiError { .. } => None, - RequestError::NetworkError(err) => Some(err), - RequestError::InvalidJson(err) => Some(err), - } - } -} - -pub type ResponseResult = Result; - pub async fn request( client: &Client, token: &str, @@ -66,12 +40,9 @@ pub async fn request( ) -> ResponseResult { let mut response = client .post(&method_url(TELEGRAM_API_URL, token, method_name)) - .apply(|request_builder| { - if let Some(params) = params { - request_builder.multipart(params) - } else { - request_builder - } + .apply(|request_builder| match params { + Some(params) => request_builder.multipart(params), + None => request_builder, }) .send() .compat() diff --git a/src/core/requests/form_builder.rs b/src/core/requests/form_builder.rs index ce4a3d39..ba38bc19 100644 --- a/src/core/requests/form_builder.rs +++ b/src/core/requests/form_builder.rs @@ -38,8 +38,8 @@ impl FormBuilder { form: self.form.text( name.to_owned(), serde_json::to_string(value).expect("serde_json::to_string failed"), - ) - } + ), + }, } } diff --git a/src/core/requests/get_me.rs b/src/core/requests/get_me.rs index 464c85bf..5f5a14fe 100644 --- a/src/core/requests/get_me.rs +++ b/src/core/requests/get_me.rs @@ -1,17 +1,10 @@ -use crate::core::{ - types::User, - network::{ - request, ResponseResult, - }, - requests::{ - Request, RequestInfo, RequestFuture, - } -}; - +use crate::core::network; +use crate::core::requests::{Request, RequestFuture, RequestInfo, ResponseResult}; +use crate::core::types::User; #[derive(Debug, Constructor)] pub struct GetMe { - info: RequestInfo + info: RequestInfo, } impl Request for GetMe { @@ -19,7 +12,7 @@ impl Request for GetMe { fn send(self) -> RequestFuture> { Box::new(async move { - request(&self.info.client, &self.info.token, "getMe", None).await + network::request(&self.info.client, &self.info.token, "getMe", None).await }) } } diff --git a/src/core/requests/mod.rs b/src/core/requests/mod.rs index 1c88f1c6..797ea3b8 100644 --- a/src/core/requests/mod.rs +++ b/src/core/requests/mod.rs @@ -1,13 +1,37 @@ use std::future::Future; -use crate::core::network::ResponseResult; - -use serde::de::DeserializeOwned; use reqwest::r#async::Client; - +use reqwest::StatusCode; +use serde::de::DeserializeOwned; mod form_builder; +#[derive(Debug, Display)] +pub enum RequestError { + #[display(fmt = "Telegram error #{}: {}", status_code, description)] + ApiError { + status_code: StatusCode, + description: String, + }, + + #[display(fmt = "Network error: {err}", err = _0)] + NetworkError(reqwest::Error), + + #[display(fmt = "InvalidJson error caused by: {err}", err = _0)] + InvalidJson(serde_json::Error), +} + +impl std::error::Error for RequestError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + RequestError::ApiError { .. } => None, + RequestError::NetworkError(err) => Some(err), + RequestError::InvalidJson(err) => Some(err), + } + } +} + +pub type ResponseResult = Result; /// Request that can be sent to telegram. /// `ReturnValue` - a type that will be returned from Telegram. diff --git a/src/core/requests/send_message.rs b/src/core/requests/send_message.rs index 95cdb319..e767d32a 100644 --- a/src/core/requests/send_message.rs +++ b/src/core/requests/send_message.rs @@ -1,17 +1,6 @@ -use crate::core::{ - types::Message, - network::{ - request, ResponseResult, - }, - requests::{ - form_builder::FormBuilder, - ChatId, - Request, - RequestInfo, - RequestFuture, - } -}; - +use crate::core::requests::form_builder::FormBuilder; +use crate::core::requests::{ChatId, Request, RequestFuture, RequestInfo, ResponseResult}; +use crate::core::{network, types::Message}; #[derive(Debug, TypedBuilder)] pub struct SendMessage { @@ -35,7 +24,6 @@ pub struct SendMessage { impl Request for SendMessage { type ReturnValue = Message; - fn send(self) -> RequestFuture> { Box::new(async move { let params = FormBuilder::new() @@ -50,7 +38,13 @@ impl Request for SendMessage { .add_if_some("reply_to_message_id", self.reply_to_message_id.as_ref()) .build(); - request(&self.info.client, &self.info.token, "sendMessage", Some(params)).await + network::request( + &self.info.client, + &self.info.token, + "sendMessage", + Some(params), + ) + .await }) } } diff --git a/src/core/types/chosen_inline_result.rs b/src/core/types/chosen_inline_result.rs index bd479fa5..489acfaa 100644 --- a/src/core/types/chosen_inline_result.rs +++ b/src/core/types/chosen_inline_result.rs @@ -1,4 +1,5 @@ use serde::Deserialize; + use crate::core::types::user::User; #[derive(Debug, Deserealize)] diff --git a/src/core/types/input_message_content.rs b/src/core/types/input_message_content.rs index 14e4b142..cf4c6873 100644 --- a/src/core/types/input_message_content.rs +++ b/src/core/types/input_message_content.rs @@ -1,4 +1,5 @@ use serde::Serialize; + use crate::core::parse_mode::ParseMode; pub enum InputMessageContent { diff --git a/src/core/types/message.rs b/src/core/types/message.rs index 2a3e3dc3..f53bb5a6 100644 --- a/src/core/types/message.rs +++ b/src/core/types/message.rs @@ -1,11 +1,9 @@ // use serde::Deserialize; use crate::core::types::{ - Animation, Audio, Chat, Contact, - Document, Game, Invoice, InlineKeyboardMarkup, - PhotoSize, MessageEntity, Location, PassportData, Poll, - Sticker, SuccessfulPayment, - User, Video, VideoNote, Venue, Voice, + Animation, Audio, Chat, Contact, Document, Game, InlineKeyboardMarkup, Invoice, Location, + MessageEntity, PassportData, PhotoSize, Poll, Sticker, SuccessfulPayment, User, Venue, Video, + VideoNote, Voice, }; #[derive(Debug, Deserialize, Hash, PartialEq, Eq)] diff --git a/src/core/types/message_entity.rs b/src/core/types/message_entity.rs index 0763727f..9235bd2f 100644 --- a/src/core/types/message_entity.rs +++ b/src/core/types/message_entity.rs @@ -1,6 +1,5 @@ use crate::core::types::User; - #[derive(Deserialize, Debug, PartialEq, Hash, Eq)] pub struct MessageEntity { #[serde(flatten)] @@ -13,10 +12,19 @@ pub struct MessageEntity { #[serde(rename_all = "snake_case")] #[serde(tag = "type")] pub enum MessageEntityKind { - Mention, Hashtag, Cashtag, BotCommand, Url, Email, PhoneNumber, - Bold, Italic, Code, Pre, + Mention, + Hashtag, + Cashtag, + BotCommand, + Url, + Email, + PhoneNumber, + Bold, + Italic, + Code, + Pre, TextLink { url: String }, - TextMention { user: User } + TextMention { user: User }, } #[test] @@ -25,12 +33,13 @@ fn recursive_kind() { assert_eq!( MessageEntity { - kind: MessageEntityKind::TextLink { url: "ya.ru".into() }, + kind: MessageEntityKind::TextLink { + url: "ya.ru".into() + }, offset: 1, length: 2 }, - from_str::( - r#"{"type":"text_link","url":"ya.ru","offset":1,"length":2}"# - ).unwrap() + from_str::(r#"{"type":"text_link","url":"ya.ru","offset":1,"length":2}"#) + .unwrap() ); } diff --git a/src/core/types/mod.rs b/src/core/types/mod.rs index 568022a3..f25ffcf5 100644 --- a/src/core/types/mod.rs +++ b/src/core/types/mod.rs @@ -1,26 +1,11 @@ -mod not_implemented_types; use self::not_implemented_types::*; - - pub use self::{ - answer_pre_checkout_query::AnswerPreCheckoutQuery, - answer_shipping_query::AnswerShippingQuery, - chat::Chat, - chat_permissions::ChatPermissions, - chat_photo::ChatPhoto, - document::Document, - invoice::Invoice, - label_price::LabeledPrice, - message::Message, - message_entity::MessageEntity, - order_info::OrderInfo, - pre_checkout_query::PreCheckoutQuery, - send_invoice::SendInvoice, - shipping_address::ShippingAddress, - shipping_option::ShippingOption, - shipping_query::ShippingQuery, - sticker::Sticker, - successful_payment::SuccessfulPayment, + answer_pre_checkout_query::AnswerPreCheckoutQuery, answer_shipping_query::AnswerShippingQuery, + chat::Chat, chat_permissions::ChatPermissions, chat_photo::ChatPhoto, document::Document, + invoice::Invoice, label_price::LabeledPrice, message::Message, message_entity::MessageEntity, + order_info::OrderInfo, pre_checkout_query::PreCheckoutQuery, send_invoice::SendInvoice, + shipping_address::ShippingAddress, shipping_option::ShippingOption, + shipping_query::ShippingQuery, sticker::Sticker, successful_payment::SuccessfulPayment, user::User, input_file::InputFile, input_media::InputMedia, @@ -37,6 +22,7 @@ mod invoice; mod label_price; mod message; mod message_entity; +mod not_implemented_types; mod order_info; mod pre_checkout_query; mod send_invoice; diff --git a/src/lib.rs b/src/lib.rs index 4f1e44c6..c9bdacec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,4 +5,4 @@ extern crate serde; #[macro_use] extern crate typed_builder; -mod core; +pub mod core;