From c732314e952cf265f6a200af8b22c6a49ff2c7c9 Mon Sep 17 00:00:00 2001 From: EdJoPaTo Date: Thu, 12 Sep 2024 13:05:49 +0200 Subject: [PATCH] refactor!: flatten the module structure traits and clients are now on the top level. Error and response structs are moved to their dedicated modules. Also, a bunch of doc comments are added so the docs.rs/frankenstein entry has somewhat better docs BREAKING CHANGE: old modules for them are gone and import is only possible from the top level. Responses moved from frankenstein::api_traits::MethodResponse to frankenstein::response::MethodResponse (and are also reexported on top level). --- src/api_params.rs | 34 +++++++++-------- ...telegram_api_impl.rs => client_reqwest.rs} | 13 +++---- .../telegram_api_impl.rs => client_ureq.rs} | 11 +++--- src/{api.rs => error.rs} | 14 +------ src/lib.rs | 38 +++++++++++++------ src/objects.rs | 7 ++-- src/parse_mode.rs | 4 ++ src/{api_traits.rs => response.rs} | 18 +++------ .../async_telegram_api.rs => trait_async.rs} | 7 ++-- .../telegram_api.rs => trait_sync.rs} | 9 ++--- 10 files changed, 79 insertions(+), 76 deletions(-) rename src/{api/async_telegram_api_impl.rs => client_reqwest.rs} (96%) rename src/{api/telegram_api_impl.rs => client_ureq.rs} (99%) rename src/{api.rs => error.rs} (52%) rename src/{api_traits.rs => response.rs} (82%) rename src/{api_traits/async_telegram_api.rs => trait_async.rs} (99%) rename src/{api_traits/telegram_api.rs => trait_sync.rs} (99%) diff --git a/src/api_params.rs b/src/api_params.rs index ef7bb9c..64a5c7d 100644 --- a/src/api_params.rs +++ b/src/api_params.rs @@ -1,21 +1,23 @@ -#![allow(deprecated)] +//! Parameters to Telegram API methods. + use crate::objects::{ - BotCommand, ChatAdministratorRights, ChatPermissions, ForceReply, InlineKeyboardMarkup, - InlineQueryResultArticle, InlineQueryResultAudio, InlineQueryResultCachedAudio, - InlineQueryResultCachedDocument, InlineQueryResultCachedGif, InlineQueryResultCachedMpeg4Gif, - InlineQueryResultCachedPhoto, InlineQueryResultCachedSticker, InlineQueryResultCachedVideo, - InlineQueryResultCachedVoice, InlineQueryResultContact, InlineQueryResultDocument, - InlineQueryResultGame, InlineQueryResultGif, InlineQueryResultLocation, - InlineQueryResultMpeg4Gif, InlineQueryResultPhoto, InlineQueryResultVenue, - InlineQueryResultVideo, InlineQueryResultVoice, InputPaidMedia, InputPollOption, InputSticker, - LabeledPrice, LinkPreviewOptions, MaskPosition, MenuButton, MessageEntity, - PassportElementErrorDataField, PassportElementErrorFile, PassportElementErrorFiles, - PassportElementErrorFrontSide, PassportElementErrorReverseSide, PassportElementErrorSelfie, - PassportElementErrorTranslationFile, PassportElementErrorTranslationFiles, - PassportElementErrorUnspecified, PollType, ReactionType, ReplyKeyboardMarkup, - ReplyKeyboardRemove, ShippingOption, StickerFormat, StickerType, WebAppInfo, + AllowedUpdate, BotCommand, ChatAdministratorRights, ChatPermissions, ForceReply, + InlineKeyboardMarkup, InlineQueryResultArticle, InlineQueryResultAudio, + InlineQueryResultCachedAudio, InlineQueryResultCachedDocument, InlineQueryResultCachedGif, + InlineQueryResultCachedMpeg4Gif, InlineQueryResultCachedPhoto, InlineQueryResultCachedSticker, + InlineQueryResultCachedVideo, InlineQueryResultCachedVoice, InlineQueryResultContact, + InlineQueryResultDocument, InlineQueryResultGame, InlineQueryResultGif, + InlineQueryResultLocation, InlineQueryResultMpeg4Gif, InlineQueryResultPhoto, + InlineQueryResultVenue, InlineQueryResultVideo, InlineQueryResultVoice, InputPaidMedia, + InputPollOption, InputSticker, LabeledPrice, LinkPreviewOptions, MaskPosition, MenuButton, + MessageEntity, PassportElementErrorDataField, PassportElementErrorFile, + PassportElementErrorFiles, PassportElementErrorFrontSide, PassportElementErrorReverseSide, + PassportElementErrorSelfie, PassportElementErrorTranslationFile, + PassportElementErrorTranslationFiles, PassportElementErrorUnspecified, PollType, ReactionType, + ReplyKeyboardMarkup, ReplyKeyboardRemove, ShippingOption, StickerFormat, StickerType, + WebAppInfo, }; -use crate::{AllowedUpdate, ParseMode}; +use crate::ParseMode; use bon::Builder; use serde::Deserialize; use serde::Serialize; diff --git a/src/api/async_telegram_api_impl.rs b/src/client_reqwest.rs similarity index 96% rename from src/api/async_telegram_api_impl.rs rename to src/client_reqwest.rs index e77e21c..c8a892c 100644 --- a/src/api/async_telegram_api_impl.rs +++ b/src/client_reqwest.rs @@ -1,5 +1,5 @@ -use super::Error; -use crate::api_traits::AsyncTelegramApi; +use crate::trait_async::AsyncTelegramApi; +use crate::Error; use async_trait::async_trait; use bon::Builder; use reqwest::multipart; @@ -8,6 +8,7 @@ use std::path::PathBuf; use std::time::Duration; use tokio::fs::File; +/// Asynchronous [`AsyncTelegramApi`] client implementation with [`reqwest`]. #[derive(Debug, Clone, Builder)] #[must_use = "API needs to be used in order to be useful"] pub struct AsyncApi { @@ -27,7 +28,7 @@ pub struct AsyncApi { impl AsyncApi { /// Create a new `AsyncApi`. You can use [`AsyncApi::new_url`] or [`AsyncApi::builder`] for more options. pub fn new(api_key: &str) -> Self { - Self::new_url(format!("{}{api_key}", super::BASE_API_URL)) + Self::new_url(format!("{}{api_key}", crate::BASE_API_URL)) } /// Create a new `AsyncApi`. You can use [`AsyncApi::builder`] for more options. @@ -142,11 +143,9 @@ impl AsyncTelegramApi for AsyncApi { #[cfg(test)] mod async_tests { - use super::AsyncApi; - use super::Error; + use super::*; use crate::api_params::SendMessageParams; - use crate::api_traits::ErrorResponse; - use crate::AsyncTelegramApi; + use crate::response::ErrorResponse; #[tokio::test] async fn async_send_message_success() { diff --git a/src/api/telegram_api_impl.rs b/src/client_ureq.rs similarity index 99% rename from src/api/telegram_api_impl.rs rename to src/client_ureq.rs index a3c79f6..8dbc4b5 100644 --- a/src/api/telegram_api_impl.rs +++ b/src/client_ureq.rs @@ -1,5 +1,5 @@ -use super::Error; -use crate::api_traits::TelegramApi; +use crate::trait_sync::TelegramApi; +use crate::Error; use bon::Builder; use multipart::client::lazy::Multipart; use serde_json::Value; @@ -7,6 +7,7 @@ use std::path::PathBuf; use std::time::Duration; use ureq::Response; +/// Synchronous [`TelegramApi`] client implementation with [`ureq`]. #[derive(Debug, Clone, Builder)] #[must_use = "API needs to be used in order to be useful"] pub struct Api { @@ -20,7 +21,7 @@ pub struct Api { impl Api { /// Create a new `Api`. You can use [`Api::new_url`] or [`Api::builder`] for more options. pub fn new(api_key: &str) -> Self { - Self::new_url(format!("{}{api_key}", super::BASE_API_URL)) + Self::new_url(format!("{}{api_key}", crate::BASE_API_URL)) } /// Create a new `Api`. You can use [`Api::builder`] for more options. @@ -210,12 +211,12 @@ mod tests { use crate::api_params::StopPollParams; use crate::api_params::UnbanChatMemberParams; use crate::api_params::UnpinChatMessageParams; - use crate::api_traits::ErrorResponse; + use crate::objects::AllowedUpdate; use crate::objects::BotCommand; use crate::objects::ChatPermissions; use crate::objects::InlineQueryResultVenue; use crate::objects::InputPollOption; - use crate::AllowedUpdate; + use crate::response::ErrorResponse; #[test] fn new_sets_correct_url() { diff --git a/src/api.rs b/src/error.rs similarity index 52% rename from src/api.rs rename to src/error.rs index 50075a0..02e6b16 100644 --- a/src/api.rs +++ b/src/error.rs @@ -1,18 +1,6 @@ -use crate::api_traits::ErrorResponse; +use crate::response::ErrorResponse; use serde::{Deserialize, Serialize}; -#[cfg(feature = "async-http-client")] -pub mod async_telegram_api_impl; -#[cfg(feature = "async-http-client")] -pub use async_telegram_api_impl::*; - -#[cfg(feature = "http-client")] -pub mod telegram_api_impl; -#[cfg(feature = "http-client")] -pub use telegram_api_impl::*; - -pub static BASE_API_URL: &str = "https://api.telegram.org/bot"; - #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, thiserror::Error)] #[non_exhaustive] #[serde(untagged)] diff --git a/src/lib.rs b/src/lib.rs index ceb47e9..f788708 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,21 +1,37 @@ -#[doc(hidden)] -#[cfg(feature = "async-http-client")] +#[cfg(feature = "reqwest")] pub use reqwest; +#[cfg(feature = "ureq")] +pub use ureq; -#[doc(hidden)] +pub use self::api_params::*; +#[cfg(feature = "async-http-client")] +pub use self::client_reqwest::*; #[cfg(feature = "http-client")] -pub use ureq; +pub use self::client_ureq::*; +pub use self::error::Error; +pub use self::objects::*; +pub use self::parse_mode::ParseMode; +pub use self::response::*; +#[cfg(feature = "async-telegram-trait")] +pub use self::trait_async::AsyncTelegramApi; +#[cfg(feature = "telegram-trait")] +pub use self::trait_sync::TelegramApi; -pub mod api; pub mod api_params; -pub mod api_traits; +#[cfg(feature = "async-http-client")] +mod client_reqwest; +#[cfg(feature = "http-client")] +mod client_ureq; +mod error; #[cfg(feature = "serde_json")] mod json; pub mod objects; mod parse_mode; +pub mod response; +#[cfg(feature = "async-telegram-trait")] +mod trait_async; +#[cfg(feature = "telegram-trait")] +mod trait_sync; -pub use api::*; -pub use api_params::*; -pub use api_traits::*; -pub use objects::*; -pub use parse_mode::*; +/// Default Bot API URL +pub const BASE_API_URL: &str = "https://api.telegram.org/bot"; diff --git a/src/objects.rs b/src/objects.rs index 3dd9e98..e971da4 100644 --- a/src/objects.rs +++ b/src/objects.rs @@ -1,10 +1,11 @@ +//! Objects returned or used with the Telegram API. + #![allow(deprecated)] -use super::api_params::FileUpload; +use crate::api_params::FileUpload; +use crate::ParseMode; use bon::Builder; use serde::{Deserialize, Serialize}; -use crate::ParseMode; - #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum StickerType { diff --git a/src/parse_mode.rs b/src/parse_mode.rs index e3bc0f1..970e5f8 100644 --- a/src/parse_mode.rs +++ b/src/parse_mode.rs @@ -5,6 +5,9 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; +/// Text Formatting Options +/// +/// See #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum ParseMode { #[serde(rename = "HTML")] @@ -18,6 +21,7 @@ pub enum ParseMode { impl FromStr for ParseMode { type Err = (); + fn from_str(s: &str) -> Result { match s { "HTML" | "Html" | "html" => Ok(Self::Html), diff --git a/src/api_traits.rs b/src/response.rs similarity index 82% rename from src/api_traits.rs rename to src/response.rs index fbc430e..886e23d 100644 --- a/src/api_traits.rs +++ b/src/response.rs @@ -1,17 +1,11 @@ -use crate::objects::{Message, ResponseParameters}; -use serde::{Deserialize, Serialize}; - -#[cfg(feature = "async-telegram-trait")] -pub mod async_telegram_api; +//! Raw response objects returned by the Telegram API. +//! +//! Mainly useful when implementing the `TelegramApi` trait. -#[cfg(feature = "telegram-trait")] -pub mod telegram_api; +#![allow(clippy::module_name_repetitions)] -#[cfg(feature = "async-telegram-trait")] -pub use async_telegram_api::*; - -#[cfg(feature = "telegram-trait")] -pub use telegram_api::*; +use crate::objects::{Message, ResponseParameters}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct MethodResponse { diff --git a/src/api_traits/async_telegram_api.rs b/src/trait_async.rs similarity index 99% rename from src/api_traits/async_telegram_api.rs rename to src/trait_async.rs index 3bc745e..f416c73 100644 --- a/src/api_traits/async_telegram_api.rs +++ b/src/trait_async.rs @@ -1,5 +1,3 @@ -use super::EditMessageResponse; -use super::MethodResponse; use crate::api_params::AddStickerToSetParams; use crate::api_params::AnswerCallbackQueryParams; use crate::api_params::AnswerInlineQueryParams; @@ -120,6 +118,7 @@ use crate::api_params::UnbanChatSenderChatParams; use crate::api_params::UnhideGeneralForumTopicParams; use crate::api_params::UnpinAllChatMessagesParams; use crate::api_params::UnpinAllForumTopicMessagesParams; +use crate::api_params::UnpinAllGeneralForumTopicMessagesParams; use crate::api_params::UnpinChatMessageParams; use crate::api_params::UploadStickerFileParams; use crate::objects::BotCommand; @@ -141,14 +140,14 @@ use crate::objects::MessageId; use crate::objects::Poll; use crate::objects::SentWebAppMessage; use crate::objects::StarTransactions; +use crate::objects::Sticker; use crate::objects::StickerSet; use crate::objects::Update; use crate::objects::User; use crate::objects::UserChatBoosts; use crate::objects::UserProfilePhotos; use crate::objects::WebhookInfo; -use crate::Sticker; -use crate::UnpinAllGeneralForumTopicMessagesParams; +use crate::response::{EditMessageResponse, MethodResponse}; use async_trait::async_trait; use std::path::PathBuf; diff --git a/src/api_traits/telegram_api.rs b/src/trait_sync.rs similarity index 99% rename from src/api_traits/telegram_api.rs rename to src/trait_sync.rs index 38dc7cc..351e942 100644 --- a/src/api_traits/telegram_api.rs +++ b/src/trait_sync.rs @@ -1,5 +1,3 @@ -use super::EditMessageResponse; -use super::MethodResponse; use crate::api_params::AddStickerToSetParams; use crate::api_params::AnswerCallbackQueryParams; use crate::api_params::AnswerInlineQueryParams; @@ -47,6 +45,7 @@ use crate::api_params::GetChatMemberCountParams; use crate::api_params::GetChatMemberParams; use crate::api_params::GetChatMenuButtonParams; use crate::api_params::GetChatParams; +use crate::api_params::GetCustomEmojiStickersParams; use crate::api_params::GetFileParams; use crate::api_params::GetGameHighScoresParams; use crate::api_params::GetMyCommandsParams; @@ -119,6 +118,7 @@ use crate::api_params::UnbanChatSenderChatParams; use crate::api_params::UnhideGeneralForumTopicParams; use crate::api_params::UnpinAllChatMessagesParams; use crate::api_params::UnpinAllForumTopicMessagesParams; +use crate::api_params::UnpinAllGeneralForumTopicMessagesParams; use crate::api_params::UnpinChatMessageParams; use crate::api_params::UploadStickerFileParams; use crate::objects::BotCommand; @@ -140,15 +140,14 @@ use crate::objects::MessageId; use crate::objects::Poll; use crate::objects::SentWebAppMessage; use crate::objects::StarTransactions; +use crate::objects::Sticker; use crate::objects::StickerSet; use crate::objects::Update; use crate::objects::User; use crate::objects::UserChatBoosts; use crate::objects::UserProfilePhotos; use crate::objects::WebhookInfo; -use crate::GetCustomEmojiStickersParams; -use crate::Sticker; -use crate::UnpinAllGeneralForumTopicMessagesParams; +use crate::response::{EditMessageResponse, MethodResponse}; use std::path::PathBuf; pub trait TelegramApi {