From 4ed4e12ec2b4804f638845919ce5e2852be6b2f7 Mon Sep 17 00:00:00 2001 From: Roman Yusufkhanov Date: Fri, 26 Jul 2024 20:14:30 +0300 Subject: [PATCH 1/4] feat: file document from bytes buffer --- examples/api_trait_implementation.rs | 4 +- src/api/async_telegram_api_impl.rs | 39 ++-- src/api/telegram_api_impl.rs | 38 ++-- src/api_params.rs | 39 ++++ src/api_traits/async_telegram_api.rs | 263 ++++++++++-------------- src/api_traits/telegram_api.rs | 288 +++++++++++---------------- 6 files changed, 304 insertions(+), 367 deletions(-) diff --git a/examples/api_trait_implementation.rs b/examples/api_trait_implementation.rs index 853f4f8..82329d5 100644 --- a/examples/api_trait_implementation.rs +++ b/examples/api_trait_implementation.rs @@ -1,8 +1,8 @@ use frankenstein::ErrorResponse; +use frankenstein::FileUploadForm; use frankenstein::SendMessageParams; use frankenstein::TelegramApi; use isahc::{prelude::*, Request}; -use std::path::PathBuf; static TOKEN: &str = "TOKEN"; static BASE_API_URL: &str = "https://api.telegram.org/bot"; @@ -106,7 +106,7 @@ impl TelegramApi for Api { &self, _method: &str, _params: T1, - _files: Vec<(&str, PathBuf)>, + _files: Vec, ) -> Result { let error = HttpError { code: 500, diff --git a/src/api/async_telegram_api_impl.rs b/src/api/async_telegram_api_impl.rs index 7d2e1c3..f4dd6c1 100644 --- a/src/api/async_telegram_api_impl.rs +++ b/src/api/async_telegram_api_impl.rs @@ -1,11 +1,12 @@ use super::Error; use super::HttpError; +use crate::api_params::FileUpload; +use crate::api_params::FileUploadForm; use crate::api_traits::AsyncTelegramApi; use crate::api_traits::ErrorResponse; use async_trait::async_trait; use reqwest::multipart; use serde_json::Value; -use std::path::PathBuf; use std::time::Duration; use tokio::fs::File; use typed_builder::TypedBuilder; @@ -133,21 +134,11 @@ impl AsyncTelegramApi for AsyncApi { &self, method: &str, params: T1, - files: Vec<(&str, PathBuf)>, + files: Vec, ) -> Result { let json_string = Self::encode_params(¶ms)?; let json_struct: Value = serde_json::from_str(&json_string).unwrap(); - let file_keys: Vec<&str> = files.iter().map(|(key, _)| *key).collect(); - let files_with_paths: Vec<(String, &str, String)> = files - .iter() - .map(|(key, path)| { - ( - (*key).to_string(), - path.to_str().unwrap(), - path.file_name().unwrap().to_str().unwrap().to_string(), - ) - }) - .collect(); + let file_keys: Vec<&str> = files.iter().map(|(key, _)| key.as_str()).collect(); let mut form = multipart::Form::new(); for (key, val) in json_struct.as_object().unwrap() { @@ -161,11 +152,25 @@ impl AsyncTelegramApi for AsyncApi { } } - for (parameter_name, file_path, file_name) in files_with_paths { - let file = File::open(file_path).await?; + for (parameter_name, file) in files { + match file { + FileUpload::InputFile(input_file) => { + let file_path = input_file.path; + let file = File::open(&file_path).await?; + let file_name = file_path.file_name().unwrap().to_str().unwrap().to_string(); - let part = multipart::Part::stream(file).file_name(file_name); - form = form.part(parameter_name, part); + let part = multipart::Part::stream(file).file_name(file_name); + form = form.part(parameter_name, part); + } + FileUpload::InputBuf(input_buf) => { + let buf = input_buf.data.clone(); + let file_name = input_buf.file_name.clone(); + + let part = multipart::Part::stream(buf).file_name(file_name); + form = form.part(parameter_name, part); + } + FileUpload::String(_) => continue, + } } let url = format!("{}/{method}", self.api_url); diff --git a/src/api/telegram_api_impl.rs b/src/api/telegram_api_impl.rs index d5c76c7..6bf9e17 100644 --- a/src/api/telegram_api_impl.rs +++ b/src/api/telegram_api_impl.rs @@ -1,10 +1,11 @@ use super::Error; use super::HttpError; +use crate::api_params::FileUpload; +use crate::api_params::FileUploadForm; use crate::api_traits::ErrorResponse; use crate::api_traits::TelegramApi; use multipart::client::lazy::Multipart; use serde_json::Value; -use std::path::PathBuf; use std::time::Duration; use typed_builder::TypedBuilder; use ureq::Response; @@ -123,15 +124,11 @@ impl TelegramApi for Api { &self, method: &str, params: T1, - files: Vec<(&str, PathBuf)>, + files: Vec, ) -> Result { let json_string = Self::encode_params(¶ms)?; let json_struct: Value = serde_json::from_str(&json_string).unwrap(); - let file_keys: Vec<&str> = files.iter().map(|(key, _)| *key).collect(); - let files_with_names: Vec<(&str, Option<&str>, PathBuf)> = files - .iter() - .map(|(key, path)| (*key, path.file_name().unwrap().to_str(), path.clone())) - .collect(); + let file_keys: Vec<&str> = files.iter().map(|(key, _)| key.as_str()).collect(); let mut form = Multipart::new(); for (key, val) in json_struct.as_object().unwrap() { @@ -145,15 +142,26 @@ impl TelegramApi for Api { } } - for (parameter_name, file_name, file_path) in files_with_names { - let file = std::fs::File::open(&file_path).unwrap(); - let file_extension = file_path - .extension() - .and_then(std::ffi::OsStr::to_str) - .unwrap_or(""); - let mime = mime_guess::from_ext(file_extension).first_or_octet_stream(); + for (parameter_name, file) in files.iter() { + match file { + FileUpload::InputFile(input_file) => { + let file = std::fs::File::open(&input_file.path).unwrap(); + let file_name = input_file.path.file_name().unwrap().to_str(); + let file_extension = + input_file.path.extension().unwrap().to_str().unwrap_or(""); + let mime = mime_guess::from_ext(file_extension).first_or_octet_stream(); - form.add_stream(parameter_name, file, file_name, Some(mime)); + form.add_stream(parameter_name, file, file_name, Some(mime)); + } + FileUpload::InputBuf(input_buf) => { + let file = std::io::Cursor::>::new(input_buf.data.clone()); + let file_extension = input_buf.file_name.rsplit_once('.').unwrap_or(("", "")).1; + let mime = mime_guess::from_ext(file_extension).first_or_octet_stream(); + + form.add_stream(parameter_name, file, Some(&input_buf.file_name), Some(mime)); + } + FileUpload::String(_) => continue, + } } let url = format!("{}/{method}", self.api_url); diff --git a/src/api_params.rs b/src/api_params.rs index 07e80cd..0cdc6b7 100644 --- a/src/api_params.rs +++ b/src/api_params.rs @@ -25,9 +25,18 @@ use typed_builder::TypedBuilder as Builder; #[serde(untagged)] pub enum FileUpload { InputFile(InputFile), + InputBuf(InputBuf), String(String), } +pub type FileUploadForm = (String, FileUpload); + +impl FileUpload { + pub fn to_form(&self, key: &str) -> FileUploadForm { + (key.to_string(), self.clone()) + } +} + impl From for FileUpload { fn from(path: PathBuf) -> Self { let input_file = InputFile { path }; @@ -36,12 +45,36 @@ impl From for FileUpload { } } +impl From<(String, Vec)> for FileUpload { + fn from((file_name, data): (String, Vec)) -> Self { + Self::InputBuf(InputBuf { file_name, data }) + } +} + impl From for FileUpload { fn from(file: InputFile) -> Self { Self::InputFile(file) } } +impl From<&InputFile> for FileUpload { + fn from(file: &InputFile) -> Self { + Self::InputFile(file.clone()) + } +} + +impl From for FileUpload { + fn from(input: InputBuf) -> Self { + Self::InputBuf(input) + } +} + +impl From<&InputBuf> for FileUpload { + fn from(input: &InputBuf) -> Self { + Self::InputBuf(input.clone()) + } +} + impl From for FileUpload { fn from(file: String) -> Self { Self::String(file) @@ -220,6 +253,12 @@ pub struct InputFile { pub path: PathBuf, } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Builder)] +pub struct InputBuf { + pub file_name: String, + pub data: Vec, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Builder)] pub struct GetUpdatesParams { #[serde(skip_serializing_if = "Option::is_none")] diff --git a/src/api_traits/async_telegram_api.rs b/src/api_traits/async_telegram_api.rs index 01cb6dd..7c8ef73 100644 --- a/src/api_traits/async_telegram_api.rs +++ b/src/api_traits/async_telegram_api.rs @@ -37,6 +37,7 @@ use crate::api_params::EditMessageReplyMarkupParams; use crate::api_params::EditMessageTextParams; use crate::api_params::ExportChatInviteLinkParams; use crate::api_params::FileUpload; +use crate::api_params::FileUploadForm; use crate::api_params::ForwardMessageParams; use crate::api_params::ForwardMessagesParams; use crate::api_params::GetBusinessConnectionParams; @@ -129,7 +130,6 @@ use crate::objects::ChatAdministratorRights; use crate::objects::ChatFullInfo; use crate::objects::ChatInviteLink; use crate::objects::ChatMember; -use crate::objects::File as FileObject; use crate::objects::ForumTopic; use crate::objects::GameHighScore; use crate::objects::InputSticker; @@ -148,7 +148,6 @@ use crate::objects::WebhookInfo; use crate::Sticker; use crate::UnpinAllGeneralForumTopicMessagesParams; use async_trait::async_trait; -use std::path::PathBuf; #[async_trait] pub trait AsyncTelegramApi { @@ -231,11 +230,9 @@ pub trait AsyncTelegramApi { params: &SendPhotoParams, ) -> Result, Self::Error> { let method_name = "sendPhoto"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.photo { - files.push(("photo", input_file.path.clone())); - } + files.push(params.photo.to_form("photo")); self.request_with_possible_form_data(method_name, params, files) .await @@ -246,14 +243,12 @@ pub trait AsyncTelegramApi { params: &SendAudioParams, ) -> Result, Self::Error> { let method_name = "sendAudio"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.audio { - files.push(("audio", input_file.path.clone())); - } + files.push(params.audio.to_form("audio")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -265,7 +260,7 @@ pub trait AsyncTelegramApi { params: &SendMediaGroupParams, ) -> Result>, Self::Error> { let method_name = "sendMediaGroup"; - let mut files: Vec<(String, PathBuf)> = vec![]; + let mut files: Vec = vec![]; let mut new_medias: Vec = vec![]; let mut file_idx = 0; @@ -274,24 +269,22 @@ pub trait AsyncTelegramApi { Media::Audio(audio) => { let mut new_audio = audio.clone(); - if let FileUpload::InputFile(input_file) = &audio.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; - new_audio.media = FileUpload::String(attach_name); + new_audio.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, audio.media.clone())); - if let Some(FileUpload::InputFile(input_file)) = &audio.thumbnail { + if let Some(thumbnail) = &audio.thumbnail { let name = format!("file{file_idx}"); let attach_name = format!("attach://{name}"); file_idx += 1; new_audio.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; new_medias.push(Media::Audio(new_audio)); @@ -300,30 +293,26 @@ pub trait AsyncTelegramApi { Media::Document(document) => { let mut new_document = document.clone(); - if let FileUpload::InputFile(input_file) = &document.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; - new_document.media = FileUpload::String(attach_name); + new_document.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, document.media.clone())); new_medias.push(Media::Document(new_document)); } Media::Photo(photo) => { let mut new_photo = photo.clone(); - if let FileUpload::InputFile(input_file) = &photo.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; - new_photo.media = FileUpload::String(attach_name); + new_photo.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, photo.media.clone())); new_medias.push(Media::Photo(new_photo)); } @@ -331,24 +320,22 @@ pub trait AsyncTelegramApi { Media::Video(video) => { let mut new_video = video.clone(); - if let FileUpload::InputFile(input_file) = &video.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; - new_video.media = FileUpload::String(attach_name); + new_video.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, video.media.clone())); - if let Some(FileUpload::InputFile(input_file)) = &video.thumbnail { + if let Some(thumbnail) = &video.thumbnail { let name = format!("file{file_idx}"); let attach_name = format!("attach://{name}"); file_idx += 1; new_video.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; new_medias.push(Media::Video(new_video)); @@ -359,12 +346,7 @@ pub trait AsyncTelegramApi { let mut new_params = params.clone(); new_params.media = new_medias; - let files_with_str_names: Vec<(&str, PathBuf)> = files - .iter() - .map(|(key, path)| (key.as_str(), path.clone())) - .collect(); - - self.request_with_possible_form_data(method_name, &new_params, files_with_str_names) + self.request_with_possible_form_data(method_name, &new_params, files) .await } @@ -373,14 +355,12 @@ pub trait AsyncTelegramApi { params: &SendDocumentParams, ) -> Result, Self::Error> { let method_name = "sendDocument"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.document { - files.push(("document", input_file.path.clone())); - } + files.push(params.document.to_form("document")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -392,14 +372,12 @@ pub trait AsyncTelegramApi { params: &SendVideoParams, ) -> Result, Self::Error> { let method_name = "sendVideo"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.video { - files.push(("video", input_file.path.clone())); - } + files.push(params.video.to_form("video")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -411,14 +389,12 @@ pub trait AsyncTelegramApi { params: &SendAnimationParams, ) -> Result, Self::Error> { let method_name = "sendAnimation"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.animation { - files.push(("animation", input_file.path.clone())); - } + files.push(params.animation.to_form("animation")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -430,11 +406,9 @@ pub trait AsyncTelegramApi { params: &SendVoiceParams, ) -> Result, Self::Error> { let method_name = "sendVoice"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.voice { - files.push(("voice", input_file.path.clone())); - } + files.push(params.voice.to_form("voice")); self.request_with_possible_form_data(method_name, params, files) .await @@ -445,14 +419,12 @@ pub trait AsyncTelegramApi { params: &SendVideoNoteParams, ) -> Result, Self::Error> { let method_name = "sendVideoNote"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.video_note { - files.push(("video_note", input_file.path.clone())); - } + files.push(params.video_note.to_form("video_note")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -539,7 +511,7 @@ pub trait AsyncTelegramApi { async fn get_file( &self, params: &GetFileParams, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { self.request("getFile", Some(params)).await } @@ -646,9 +618,9 @@ pub trait AsyncTelegramApi { &self, params: &SetChatPhotoParams, ) -> Result, Self::Error> { - let photo = ¶ms.photo; + let photo = FileUpload::from(¶ms.photo); - self.request_with_form_data("setChatPhoto", params, vec![("photo", photo.path.clone())]) + self.request_with_form_data("setChatPhoto", params, vec![photo.to_form("photo")]) .await } @@ -937,28 +909,26 @@ pub trait AsyncTelegramApi { params: &EditMessageMediaParams, ) -> Result { let method_name = "editMessageMedia"; - let mut files: Vec<(String, PathBuf)> = vec![]; + let mut files: Vec = vec![]; let new_media = match ¶ms.media { InputMedia::Animation(animation) => { let mut new_animation = animation.clone(); - if let FileUpload::InputFile(input_file) = &animation.media { - let name = "animation".to_string(); - let attach_name = format!("attach://{name}"); + let name = "animation".to_string(); + let attach_name = format!("attach://{name}"); - new_animation.media = FileUpload::String(attach_name); + new_animation.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, animation.media.clone())); - if let Some(FileUpload::InputFile(input_file)) = &animation.thumbnail { + if let Some(thumbnail) = &animation.thumbnail { let name = "animation_thumb".to_string(); let attach_name = format!("attach://{name}"); new_animation.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Animation(new_animation) @@ -966,22 +936,20 @@ pub trait AsyncTelegramApi { InputMedia::Document(document) => { let mut new_document = document.clone(); - if let FileUpload::InputFile(input_file) = &document.media { - let name = "document".to_string(); - let attach_name = format!("attach://{name}"); + let name = "document".to_string(); + let attach_name = format!("attach://{name}"); - new_document.media = FileUpload::String(attach_name); + new_document.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, document.media.clone())); - if let Some(FileUpload::InputFile(input_file)) = &document.thumbnail { + if let Some(thumbnail) = &document.thumbnail { let name = "document_thumb".to_string(); let attach_name = format!("attach://{name}"); new_document.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Document(new_document) @@ -989,22 +957,20 @@ pub trait AsyncTelegramApi { InputMedia::Audio(audio) => { let mut new_audio = audio.clone(); - if let FileUpload::InputFile(input_file) = &audio.media { - let name = "audio".to_string(); - let attach_name = format!("attach://{name}"); + let name = "audio".to_string(); + let attach_name = format!("attach://{name}"); - new_audio.media = FileUpload::String(attach_name); + new_audio.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, audio.media.clone())); - if let Some(FileUpload::InputFile(input_file)) = &audio.thumbnail { + if let Some(thumbnail) = &audio.thumbnail { let name = "audio_thumb".to_string(); let attach_name = format!("attach://{name}"); new_audio.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Audio(new_audio) @@ -1012,36 +978,32 @@ pub trait AsyncTelegramApi { InputMedia::Photo(photo) => { let mut new_photo = photo.clone(); - if let FileUpload::InputFile(input_file) = &photo.media { - let name = "photo".to_string(); - let attach_name = format!("attach://{name}"); + let name = "photo".to_string(); + let attach_name = format!("attach://{name}"); - new_photo.media = FileUpload::String(attach_name); + new_photo.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, photo.media.clone())); InputMedia::Photo(new_photo) } InputMedia::Video(video) => { let mut new_video = video.clone(); - if let FileUpload::InputFile(input_file) = &video.media { - let name = "video".to_string(); - let attach_name = format!("attach://{name}"); + let name = "video".to_string(); + let attach_name = format!("attach://{name}"); - new_video.media = FileUpload::String(attach_name); + new_video.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, video.media.clone())); - if let Some(FileUpload::InputFile(input_file)) = &video.thumbnail { + if let Some(thumbnail) = &video.thumbnail { let name = "video_thumb".to_string(); let attach_name = format!("attach://{name}"); new_video.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Video(new_video) @@ -1051,12 +1013,7 @@ pub trait AsyncTelegramApi { let mut new_params = params.clone(); new_params.media = new_media; - let files_with_str_names: Vec<(&str, PathBuf)> = files - .iter() - .map(|(key, path)| (key.as_str(), path.clone())) - .collect(); - - self.request_with_possible_form_data(method_name, &new_params, files_with_str_names) + self.request_with_possible_form_data(method_name, &new_params, files) .await } @@ -1093,11 +1050,9 @@ pub trait AsyncTelegramApi { params: &SendStickerParams, ) -> Result, Self::Error> { let method_name = "sendSticker"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.sticker { - files.push(("sticker", input_file.path.clone())); - } + files.push(params.sticker.to_form("sticker")); self.request_with_possible_form_data(method_name, params, files) .await @@ -1113,13 +1068,13 @@ pub trait AsyncTelegramApi { async fn upload_sticker_file( &self, params: &UploadStickerFileParams, - ) -> Result, Self::Error> { - let sticker = ¶ms.sticker; + ) -> Result, Self::Error> { + let sticker = FileUpload::from(¶ms.sticker); self.request_with_form_data( "uploadStickerFile", params, - vec![("sticker", sticker.path.clone())], + vec![sticker.to_form("sticker")], ) .await } @@ -1130,21 +1085,17 @@ pub trait AsyncTelegramApi { ) -> Result, Self::Error> { let method_name = "createNewStickerSet"; let mut new_stickers: Vec = vec![]; - let mut files: Vec<(String, PathBuf)> = vec![]; - let mut file_idx = 0; + let mut files: Vec = vec![]; - for sticker in ¶ms.stickers { + for (file_idx, sticker) in params.stickers.iter().enumerate() { let mut new_sticker = sticker.clone(); - if let FileUpload::InputFile(input_file) = &sticker.sticker { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); - new_sticker.sticker = FileUpload::String(attach_name); + new_sticker.sticker = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push((name, sticker.sticker.clone())); new_stickers.push(new_sticker); } @@ -1152,12 +1103,7 @@ pub trait AsyncTelegramApi { let mut new_params = params.clone(); new_params.stickers = new_stickers; - let files_with_str_names: Vec<(&str, PathBuf)> = files - .iter() - .map(|(key, path)| (key.as_str(), path.clone())) - .collect(); - - self.request_with_possible_form_data(method_name, &new_params, files_with_str_names) + self.request_with_possible_form_data(method_name, &new_params, files) .await } @@ -1167,16 +1113,15 @@ pub trait AsyncTelegramApi { ) -> Result>, Self::Error> { self.request("getCustomEmojiStickers", Some(params)).await } + async fn add_sticker_to_set( &self, params: &AddStickerToSetParams, ) -> Result, Self::Error> { let method_name = "addStickerToSet"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.sticker.sticker { - files.push(("sticker", input_file.path.clone())); - } + files.push(params.sticker.sticker.to_form("sticker")); self.request_with_possible_form_data(method_name, params, files) .await @@ -1236,10 +1181,10 @@ pub trait AsyncTelegramApi { params: &SetStickerSetThumbnailParams, ) -> Result, Self::Error> { let method_name = "setStickerSetThumbnail"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -1394,7 +1339,7 @@ pub trait AsyncTelegramApi { &self, method_name: &str, params: T1, - files: Vec<(&str, PathBuf)>, + files: Vec, ) -> Result { if files.is_empty() { self.request(method_name, Some(params)).await @@ -1411,6 +1356,6 @@ pub trait AsyncTelegramApi { &self, method: &str, params: T1, - files: Vec<(&str, PathBuf)>, + files: Vec, ) -> Result; } diff --git a/src/api_traits/telegram_api.rs b/src/api_traits/telegram_api.rs index 24aa058..a850fb4 100644 --- a/src/api_traits/telegram_api.rs +++ b/src/api_traits/telegram_api.rs @@ -37,6 +37,7 @@ use crate::api_params::EditMessageReplyMarkupParams; use crate::api_params::EditMessageTextParams; use crate::api_params::ExportChatInviteLinkParams; use crate::api_params::FileUpload; +use crate::api_params::FileUploadForm; use crate::api_params::ForwardMessageParams; use crate::api_params::ForwardMessagesParams; use crate::api_params::GetBusinessConnectionParams; @@ -147,7 +148,6 @@ use crate::objects::WebhookInfo; use crate::GetCustomEmojiStickersParams; use crate::Sticker; use crate::UnpinAllGeneralForumTopicMessagesParams; -use std::path::PathBuf; pub trait TelegramApi { type Error; @@ -223,25 +223,21 @@ pub trait TelegramApi { fn send_photo(&self, params: &SendPhotoParams) -> Result, Self::Error> { let method_name = "sendPhoto"; - let mut files: Vec<(&str, PathBuf)> = vec![]; - - if let FileUpload::InputFile(input_file) = ¶ms.photo { - files.push(("photo", input_file.path.clone())); - } - - self.request_with_possible_form_data(method_name, params, files) + self.request_with_possible_form_data( + method_name, + params, + vec![params.photo.to_form("photo")], + ) } fn send_audio(&self, params: &SendAudioParams) -> Result, Self::Error> { let method_name = "sendAudio"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.audio { - files.push(("audio", input_file.path.clone())); - } + files.push(params.audio.to_form("audio")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(input_file) = ¶ms.thumbnail { + files.push(input_file.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -252,7 +248,7 @@ pub trait TelegramApi { params: &SendMediaGroupParams, ) -> Result>, Self::Error> { let method_name = "sendMediaGroup"; - let mut files: Vec<(String, PathBuf)> = vec![]; + let mut files: Vec = vec![]; let mut new_medias: Vec = vec![]; let mut file_idx = 0; @@ -261,24 +257,22 @@ pub trait TelegramApi { Media::Audio(audio) => { let mut new_audio = audio.clone(); - if let FileUpload::InputFile(input_file) = &audio.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; - new_audio.media = FileUpload::String(attach_name); + new_audio.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(audio.media.to_form(&name)); - if let Some(FileUpload::InputFile(input_file)) = &audio.thumbnail { + if let Some(thumbnail) = &audio.thumbnail { let name = format!("file{file_idx}"); let attach_name = format!("attach://{name}"); file_idx += 1; new_audio.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; new_medias.push(Media::Audio(new_audio)); @@ -287,30 +281,24 @@ pub trait TelegramApi { Media::Document(document) => { let mut new_document = document.clone(); - if let FileUpload::InputFile(input_file) = &document.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_document.media = FileUpload::String(attach_name); + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; + new_document.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(document.media.to_form(&name)); new_medias.push(Media::Document(new_document)); } Media::Photo(photo) => { let mut new_photo = photo.clone(); - if let FileUpload::InputFile(input_file) = &photo.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_photo.media = FileUpload::String(attach_name); + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; + new_photo.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(photo.media.to_form(&name)); new_medias.push(Media::Photo(new_photo)); } @@ -318,24 +306,21 @@ pub trait TelegramApi { Media::Video(video) => { let mut new_video = video.clone(); - if let FileUpload::InputFile(input_file) = &video.media { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_video.media = FileUpload::String(attach_name); + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); + file_idx += 1; + new_video.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(video.media.to_form(&name)); - if let Some(FileUpload::InputFile(input_file)) = &video.thumbnail { + if let Some(thumbnail) = &video.thumbnail { let name = format!("file{file_idx}"); let attach_name = format!("attach://{name}"); file_idx += 1; new_video.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; new_medias.push(Media::Video(new_video)); @@ -346,12 +331,7 @@ pub trait TelegramApi { let mut new_params = params.clone(); new_params.media = new_medias; - let files_with_str_names: Vec<(&str, PathBuf)> = files - .iter() - .map(|(key, path)| (key.as_str(), path.clone())) - .collect(); - - self.request_with_possible_form_data(method_name, &new_params, files_with_str_names) + self.request_with_possible_form_data(method_name, &new_params, files) } fn send_document( @@ -359,14 +339,12 @@ pub trait TelegramApi { params: &SendDocumentParams, ) -> Result, Self::Error> { let method_name = "sendDocument"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.document { - files.push(("document", input_file.path.clone())); - } + files.push(params.document.to_form("document")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -374,14 +352,12 @@ pub trait TelegramApi { fn send_video(&self, params: &SendVideoParams) -> Result, Self::Error> { let method_name = "sendVideo"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.video { - files.push(("video", input_file.path.clone())); - } + files.push(params.video.to_form("video")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -392,14 +368,12 @@ pub trait TelegramApi { params: &SendAnimationParams, ) -> Result, Self::Error> { let method_name = "sendAnimation"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.animation { - files.push(("animation", input_file.path.clone())); - } + files.push(params.animation.to_form("animation")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -407,13 +381,11 @@ pub trait TelegramApi { fn send_voice(&self, params: &SendVoiceParams) -> Result, Self::Error> { let method_name = "sendVoice"; - let mut files: Vec<(&str, PathBuf)> = vec![]; - - if let FileUpload::InputFile(input_file) = ¶ms.voice { - files.push(("voice", input_file.path.clone())); - } - - self.request_with_possible_form_data(method_name, params, files) + self.request_with_possible_form_data( + method_name, + params, + vec![params.voice.to_form("voice")], + ) } fn send_video_note( @@ -421,14 +393,12 @@ pub trait TelegramApi { params: &SendVideoNoteParams, ) -> Result, Self::Error> { let method_name = "sendVideoNote"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let FileUpload::InputFile(input_file) = ¶ms.video_note { - files.push(("video_note", input_file.path.clone())); - } + files.push(params.video_note.to_form("video_note")); - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -608,9 +578,8 @@ pub trait TelegramApi { &self, params: &SetChatPhotoParams, ) -> Result, Self::Error> { - let photo = ¶ms.photo; - - self.request_with_form_data("setChatPhoto", params, vec![("photo", photo.path.clone())]) + let photo = FileUpload::from(¶ms.photo); + self.request_with_form_data("setChatPhoto", params, vec![photo.to_form("photo")]) } fn delete_chat_photo( @@ -889,28 +858,26 @@ pub trait TelegramApi { params: &EditMessageMediaParams, ) -> Result { let method_name = "editMessageMedia"; - let mut files: Vec<(String, PathBuf)> = vec![]; + let mut files: Vec = vec![]; let new_media = match ¶ms.media { InputMedia::Animation(animation) => { let mut new_animation = animation.clone(); - if let FileUpload::InputFile(input_file) = &animation.media { - let name = "animation".to_string(); - let attach_name = format!("attach://{name}"); + let name = "animation".to_string(); + let attach_name = format!("attach://{name}"); - new_animation.media = FileUpload::String(attach_name); + new_animation.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(animation.media.to_form(&name)); - if let Some(FileUpload::InputFile(input_file)) = &animation.thumbnail { + if let Some(thumbnail) = &animation.thumbnail { let name = "animation_thumb".to_string(); let attach_name = format!("attach://{name}"); new_animation.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Animation(new_animation) @@ -918,22 +885,20 @@ pub trait TelegramApi { InputMedia::Document(document) => { let mut new_document = document.clone(); - if let FileUpload::InputFile(input_file) = &document.media { - let name = "document".to_string(); - let attach_name = format!("attach://{name}"); + let name = "document".to_string(); + let attach_name = format!("attach://{name}"); - new_document.media = FileUpload::String(attach_name); + new_document.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(document.media.to_form(&name)); - if let Some(FileUpload::InputFile(input_file)) = &document.thumbnail { + if let Some(thumbnail) = &document.thumbnail { let name = "document_thumb".to_string(); let attach_name = format!("attach://{name}"); new_document.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Document(new_document) @@ -941,22 +906,20 @@ pub trait TelegramApi { InputMedia::Audio(audio) => { let mut new_audio = audio.clone(); - if let FileUpload::InputFile(input_file) = &audio.media { - let name = "audio".to_string(); - let attach_name = format!("attach://{name}"); + let name = "audio".to_string(); + let attach_name = format!("attach://{name}"); - new_audio.media = FileUpload::String(attach_name); + new_audio.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(audio.media.to_form(&name)); - if let Some(FileUpload::InputFile(input_file)) = &audio.thumbnail { + if let Some(thumbnail) = &audio.thumbnail { let name = "audio_thumb".to_string(); let attach_name = format!("attach://{name}"); new_audio.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Audio(new_audio) @@ -964,36 +927,32 @@ pub trait TelegramApi { InputMedia::Photo(photo) => { let mut new_photo = photo.clone(); - if let FileUpload::InputFile(input_file) = &photo.media { - let name = "photo".to_string(); - let attach_name = format!("attach://{name}"); + let name = "photo".to_string(); + let attach_name = format!("attach://{name}"); - new_photo.media = FileUpload::String(attach_name); + new_photo.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(photo.media.to_form(&name)); InputMedia::Photo(new_photo) } InputMedia::Video(video) => { let mut new_video = video.clone(); - if let FileUpload::InputFile(input_file) = &video.media { - let name = "video".to_string(); - let attach_name = format!("attach://{name}"); + let name = "video".to_string(); + let attach_name = format!("attach://{name}"); - new_video.media = FileUpload::String(attach_name); + new_video.media = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(video.media.to_form(&name)); - if let Some(FileUpload::InputFile(input_file)) = &video.thumbnail { + if let Some(thumbnail) = &video.thumbnail { let name = "video_thumb".to_string(); let attach_name = format!("attach://{name}"); new_video.thumbnail = Some(FileUpload::String(attach_name)); - files.push((name, input_file.path.clone())); + files.push(thumbnail.to_form(&name)); }; InputMedia::Video(new_video) @@ -1003,12 +962,7 @@ pub trait TelegramApi { let mut new_params = params.clone(); new_params.media = new_media; - let files_with_str_names: Vec<(&str, PathBuf)> = files - .iter() - .map(|(key, path)| (key.as_str(), path.clone())) - .collect(); - - self.request_with_possible_form_data(method_name, &new_params, files_with_str_names) + self.request_with_possible_form_data(method_name, &new_params, files) } fn edit_message_reply_markup( @@ -1041,13 +995,11 @@ pub trait TelegramApi { params: &SendStickerParams, ) -> Result, Self::Error> { let method_name = "sendSticker"; - let mut files: Vec<(&str, PathBuf)> = vec![]; - - if let FileUpload::InputFile(input_file) = ¶ms.sticker { - files.push(("sticker", input_file.path.clone())); - } - - self.request_with_possible_form_data(method_name, params, files) + self.request_with_possible_form_data( + method_name, + params, + vec![params.sticker.to_form("sticker")], + ) } fn get_sticker_set( @@ -1060,13 +1012,12 @@ pub trait TelegramApi { fn upload_sticker_file( &self, params: &UploadStickerFileParams, - ) -> Result, Self::Error> { - let sticker = ¶ms.sticker; - + ) -> Result, Self::Error> { + let sticker = FileUpload::from(¶ms.sticker); self.request_with_form_data( "uploadStickerFile", params, - vec![("sticker", sticker.path.clone())], + vec![sticker.to_form("sticker")], ) } @@ -1076,21 +1027,17 @@ pub trait TelegramApi { ) -> Result, Self::Error> { let method_name = "createNewStickerSet"; let mut new_stickers: Vec = vec![]; - let mut files: Vec<(String, PathBuf)> = vec![]; - let mut file_idx = 0; + let mut files: Vec = vec![]; - for sticker in ¶ms.stickers { + for (file_idx, sticker) in params.stickers.iter().enumerate() { let mut new_sticker = sticker.clone(); - if let FileUpload::InputFile(input_file) = &sticker.sticker { - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; + let name = format!("file{file_idx}"); + let attach_name = format!("attach://{name}"); - new_sticker.sticker = FileUpload::String(attach_name); + new_sticker.sticker = FileUpload::String(attach_name); - files.push((name, input_file.path.clone())); - }; + files.push(sticker.sticker.to_form(&name)); new_stickers.push(new_sticker); } @@ -1098,12 +1045,7 @@ pub trait TelegramApi { let mut new_params = params.clone(); new_params.stickers = new_stickers; - let files_with_str_names: Vec<(&str, PathBuf)> = files - .iter() - .map(|(key, path)| (key.as_str(), path.clone())) - .collect(); - - self.request_with_possible_form_data(method_name, &new_params, files_with_str_names) + self.request_with_possible_form_data(method_name, &new_params, files) } fn get_custom_emoji_stickers( @@ -1118,13 +1060,11 @@ pub trait TelegramApi { params: &AddStickerToSetParams, ) -> Result, Self::Error> { let method_name = "addStickerToSet"; - let mut files: Vec<(&str, PathBuf)> = vec![]; - - if let FileUpload::InputFile(input_file) = ¶ms.sticker.sticker { - files.push(("sticker", input_file.path.clone())); - } - - self.request_with_possible_form_data(method_name, params, files) + self.request_with_possible_form_data( + method_name, + params, + vec![params.sticker.sticker.to_form("sticker")], + ) } fn set_sticker_position_in_set( @@ -1181,10 +1121,10 @@ pub trait TelegramApi { params: &SetStickerSetThumbnailParams, ) -> Result, Self::Error> { let method_name = "setStickerSetThumbnail"; - let mut files: Vec<(&str, PathBuf)> = vec![]; + let mut files: Vec = vec![]; - if let Some(FileUpload::InputFile(input_file)) = ¶ms.thumbnail { - files.push(("thumbnail", input_file.path.clone())); + if let Some(thumbnail) = ¶ms.thumbnail { + files.push(thumbnail.to_form("thumbnail")); } self.request_with_possible_form_data(method_name, params, files) @@ -1322,7 +1262,7 @@ pub trait TelegramApi { &self, method_name: &str, params: &T1, - files: Vec<(&str, PathBuf)>, + files: Vec, ) -> Result { if files.is_empty() { self.request(method_name, Some(params)) @@ -1338,7 +1278,7 @@ pub trait TelegramApi { &self, method: &str, params: T1, - files: Vec<(&str, PathBuf)>, + files: Vec, ) -> Result; fn request( From 9d4d8d9361d37128c929c6e32cd0fcc96e13f6f1 Mon Sep 17 00:00:00 2001 From: Roman Yusufkhanov Date: Fri, 26 Jul 2024 20:31:47 +0300 Subject: [PATCH 2/4] fix cargo clippy --- src/api/telegram_api_impl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/telegram_api_impl.rs b/src/api/telegram_api_impl.rs index 6bf9e17..8c2905e 100644 --- a/src/api/telegram_api_impl.rs +++ b/src/api/telegram_api_impl.rs @@ -142,7 +142,7 @@ impl TelegramApi for Api { } } - for (parameter_name, file) in files.iter() { + for (parameter_name, file) in &files { match file { FileUpload::InputFile(input_file) => { let file = std::fs::File::open(&input_file.path).unwrap(); From 225e80ca42ce6ff571bbd437f1d48b72b457c6a2 Mon Sep 17 00:00:00 2001 From: Roman Yusufkhanov Date: Sat, 27 Jul 2024 00:02:23 +0300 Subject: [PATCH 3/4] fix uploads push --- src/api_params.rs | 6 +- src/api_traits/async_telegram_api.rs | 266 +++++++++++++----------- src/api_traits/telegram_api.rs | 293 +++++++++++++++------------ 3 files changed, 320 insertions(+), 245 deletions(-) diff --git a/src/api_params.rs b/src/api_params.rs index 0cdc6b7..e20a506 100644 --- a/src/api_params.rs +++ b/src/api_params.rs @@ -32,9 +32,13 @@ pub enum FileUpload { pub type FileUploadForm = (String, FileUpload); impl FileUpload { - pub fn to_form(&self, key: &str) -> FileUploadForm { + pub fn to_form_with_key(&self, key: &str) -> FileUploadForm { (key.to_string(), self.clone()) } + + pub fn is_input(&self) -> bool { + matches!(self, FileUpload::InputFile(_) | FileUpload::InputBuf(_)) + } } impl From for FileUpload { diff --git a/src/api_traits/async_telegram_api.rs b/src/api_traits/async_telegram_api.rs index 7c8ef73..f2943dd 100644 --- a/src/api_traits/async_telegram_api.rs +++ b/src/api_traits/async_telegram_api.rs @@ -130,6 +130,7 @@ use crate::objects::ChatAdministratorRights; use crate::objects::ChatFullInfo; use crate::objects::ChatInviteLink; use crate::objects::ChatMember; +use crate::objects::File as FileObject; use crate::objects::ForumTopic; use crate::objects::GameHighScore; use crate::objects::InputSticker; @@ -232,7 +233,9 @@ pub trait AsyncTelegramApi { let method_name = "sendPhoto"; let mut files: Vec = vec![]; - files.push(params.photo.to_form("photo")); + if params.photo.is_input() { + files.push(params.photo.to_form_with_key("photo")); + } self.request_with_possible_form_data(method_name, params, files) .await @@ -245,10 +248,14 @@ pub trait AsyncTelegramApi { let method_name = "sendAudio"; let mut files: Vec = vec![]; - files.push(params.audio.to_form("audio")); + if params.audio.is_input() { + files.push(params.audio.to_form_with_key("audio")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -269,23 +276,24 @@ pub trait AsyncTelegramApi { Media::Audio(audio) => { let mut new_audio = audio.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_audio.media = FileUpload::String(attach_name); - - files.push((name, audio.media.clone())); - - if let Some(thumbnail) = &audio.thumbnail { + if audio.media.is_input() { let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); file_idx += 1; - new_audio.thumbnail = Some(FileUpload::String(attach_name)); + new_audio.media = FileUpload::String(format!("attach://{name}")); + files.push(audio.media.to_form_with_key(&name)); + } + + if let Some(thumbnail) = &audio.thumbnail { + if thumbnail.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push(thumbnail.to_form(&name)); - }; + new_audio.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(&name)); + } + } new_medias.push(Media::Audio(new_audio)); } @@ -293,26 +301,27 @@ pub trait AsyncTelegramApi { Media::Document(document) => { let mut new_document = document.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_document.media = FileUpload::String(attach_name); + if document.media.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push((name, document.media.clone())); + new_document.media = FileUpload::String(format!("attach://{name}")); + files.push(document.media.to_form_with_key(&name)); + } new_medias.push(Media::Document(new_document)); } + Media::Photo(photo) => { let mut new_photo = photo.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_photo.media = FileUpload::String(attach_name); + if photo.media.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push((name, photo.media.clone())); + new_photo.media = FileUpload::String(format!("attach://{name}")); + files.push(photo.media.to_form_with_key(&name)); + } new_medias.push(Media::Photo(new_photo)); } @@ -320,23 +329,24 @@ pub trait AsyncTelegramApi { Media::Video(video) => { let mut new_video = video.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_video.media = FileUpload::String(attach_name); - - files.push((name, video.media.clone())); - - if let Some(thumbnail) = &video.thumbnail { + if video.media.is_input() { let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); file_idx += 1; - new_video.thumbnail = Some(FileUpload::String(attach_name)); + new_video.media = FileUpload::String(format!("attach://{name}")); + files.push(video.media.to_form_with_key(&name)); + } + + if let Some(thumbnail) = &video.thumbnail { + if thumbnail.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push(thumbnail.to_form(&name)); - }; + new_video.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(&name)); + } + } new_medias.push(Media::Video(new_video)); } @@ -357,10 +367,14 @@ pub trait AsyncTelegramApi { let method_name = "sendDocument"; let mut files: Vec = vec![]; - files.push(params.document.to_form("document")); + if params.document.is_input() { + files.push(params.document.to_form_with_key("document")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -374,10 +388,14 @@ pub trait AsyncTelegramApi { let method_name = "sendVideo"; let mut files: Vec = vec![]; - files.push(params.video.to_form("video")); + if params.video.is_input() { + files.push(params.video.to_form_with_key("video")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -391,10 +409,14 @@ pub trait AsyncTelegramApi { let method_name = "sendAnimation"; let mut files: Vec = vec![]; - files.push(params.animation.to_form("animation")); + if params.animation.is_input() { + files.push(params.animation.to_form_with_key("animation")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -408,7 +430,9 @@ pub trait AsyncTelegramApi { let method_name = "sendVoice"; let mut files: Vec = vec![]; - files.push(params.voice.to_form("voice")); + if params.voice.is_input() { + files.push(params.voice.to_form_with_key("voice")); + } self.request_with_possible_form_data(method_name, params, files) .await @@ -421,10 +445,14 @@ pub trait AsyncTelegramApi { let method_name = "sendVideoNote"; let mut files: Vec = vec![]; - files.push(params.video_note.to_form("video_note")); + if params.video_note.is_input() { + files.push(params.video_note.to_form_with_key("video_note")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -511,7 +539,7 @@ pub trait AsyncTelegramApi { async fn get_file( &self, params: &GetFileParams, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { self.request("getFile", Some(params)).await } @@ -620,8 +648,12 @@ pub trait AsyncTelegramApi { ) -> Result, Self::Error> { let photo = FileUpload::from(¶ms.photo); - self.request_with_form_data("setChatPhoto", params, vec![photo.to_form("photo")]) - .await + self.request_with_form_data( + "setChatPhoto", + params, + vec![photo.to_form_with_key("photo")], + ) + .await } async fn delete_chat_photo( @@ -915,20 +947,19 @@ pub trait AsyncTelegramApi { InputMedia::Animation(animation) => { let mut new_animation = animation.clone(); - let name = "animation".to_string(); - let attach_name = format!("attach://{name}"); - - new_animation.media = FileUpload::String(attach_name); - - files.push((name, animation.media.clone())); + if animation.media.is_input() { + let name = "animation"; + new_animation.media = FileUpload::String(format!("attach://{name}")); + files.push(animation.media.to_form_with_key(name)); + } if let Some(thumbnail) = &animation.thumbnail { - let name = "animation_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_animation.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "animation_thumb"; + new_animation.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Animation(new_animation) @@ -936,20 +967,19 @@ pub trait AsyncTelegramApi { InputMedia::Document(document) => { let mut new_document = document.clone(); - let name = "document".to_string(); - let attach_name = format!("attach://{name}"); - - new_document.media = FileUpload::String(attach_name); - - files.push((name, document.media.clone())); + if document.media.is_input() { + let name = "document"; + new_document.media = FileUpload::String(format!("attach://{name}")); + files.push(document.media.to_form_with_key(name)); + } if let Some(thumbnail) = &document.thumbnail { - let name = "document_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_document.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "document_thumb"; + new_document.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Document(new_document) @@ -957,20 +987,18 @@ pub trait AsyncTelegramApi { InputMedia::Audio(audio) => { let mut new_audio = audio.clone(); - let name = "audio".to_string(); - let attach_name = format!("attach://{name}"); - - new_audio.media = FileUpload::String(attach_name); - - files.push((name, audio.media.clone())); + if audio.media.is_input() { + let name = "audio"; + new_audio.media = FileUpload::String(format!("attach://{name}")); + files.push(audio.media.to_form_with_key(name)); + } if let Some(thumbnail) = &audio.thumbnail { - let name = "audio_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_audio.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "audio_thumb"; + new_audio.thumbnail = Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Audio(new_audio) @@ -978,32 +1006,29 @@ pub trait AsyncTelegramApi { InputMedia::Photo(photo) => { let mut new_photo = photo.clone(); - let name = "photo".to_string(); - let attach_name = format!("attach://{name}"); - - new_photo.media = FileUpload::String(attach_name); - - files.push((name, photo.media.clone())); + if photo.media.is_input() { + let name = "photo"; + new_photo.media = FileUpload::String(format!("attach://{name}")); + files.push(photo.media.to_form_with_key(name)); + } InputMedia::Photo(new_photo) } InputMedia::Video(video) => { let mut new_video = video.clone(); - let name = "video".to_string(); - let attach_name = format!("attach://{name}"); - - new_video.media = FileUpload::String(attach_name); - - files.push((name, video.media.clone())); + if video.media.is_input() { + let name = "video"; + new_video.media = FileUpload::String(format!("attach://{name}")); + files.push(video.media.to_form_with_key(name)); + } if let Some(thumbnail) = &video.thumbnail { - let name = "video_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_video.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "video_thumb"; + new_video.thumbnail = Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Video(new_video) @@ -1052,7 +1077,9 @@ pub trait AsyncTelegramApi { let method_name = "sendSticker"; let mut files: Vec = vec![]; - files.push(params.sticker.to_form("sticker")); + if params.sticker.is_input() { + files.push(params.sticker.to_form_with_key("sticker")); + } self.request_with_possible_form_data(method_name, params, files) .await @@ -1074,7 +1101,7 @@ pub trait AsyncTelegramApi { self.request_with_form_data( "uploadStickerFile", params, - vec![sticker.to_form("sticker")], + vec![sticker.to_form_with_key("sticker")], ) .await } @@ -1086,16 +1113,19 @@ pub trait AsyncTelegramApi { let method_name = "createNewStickerSet"; let mut new_stickers: Vec = vec![]; let mut files: Vec = vec![]; + let mut file_idx = 0; - for (file_idx, sticker) in params.stickers.iter().enumerate() { + for sticker in ¶ms.stickers { let mut new_sticker = sticker.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); + if sticker.sticker.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - new_sticker.sticker = FileUpload::String(attach_name); + new_sticker.sticker = FileUpload::String(format!("attach://{name}")); - files.push((name, sticker.sticker.clone())); + files.push(sticker.sticker.to_form_with_key(&name)); + } new_stickers.push(new_sticker); } @@ -1121,7 +1151,9 @@ pub trait AsyncTelegramApi { let method_name = "addStickerToSet"; let mut files: Vec = vec![]; - files.push(params.sticker.sticker.to_form("sticker")); + if params.sticker.sticker.is_input() { + files.push(params.sticker.sticker.to_form_with_key("sticker")); + } self.request_with_possible_form_data(method_name, params, files) .await @@ -1184,7 +1216,9 @@ pub trait AsyncTelegramApi { let mut files: Vec = vec![]; if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) diff --git a/src/api_traits/telegram_api.rs b/src/api_traits/telegram_api.rs index a850fb4..dd5a05f 100644 --- a/src/api_traits/telegram_api.rs +++ b/src/api_traits/telegram_api.rs @@ -223,21 +223,27 @@ pub trait TelegramApi { fn send_photo(&self, params: &SendPhotoParams) -> Result, Self::Error> { let method_name = "sendPhoto"; - self.request_with_possible_form_data( - method_name, - params, - vec![params.photo.to_form("photo")], - ) + let mut files: Vec = vec![]; + + if params.photo.is_input() { + files.push(params.photo.to_form_with_key("photo")); + } + + self.request_with_possible_form_data(method_name, params, files) } fn send_audio(&self, params: &SendAudioParams) -> Result, Self::Error> { let method_name = "sendAudio"; let mut files: Vec = vec![]; - files.push(params.audio.to_form("audio")); + if params.audio.is_input() { + files.push(params.audio.to_form_with_key("audio")); + } - if let Some(input_file) = ¶ms.thumbnail { - files.push(input_file.to_form("thumbnail")); + if let Some(thumbnail) = ¶ms.thumbnail { + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -257,23 +263,24 @@ pub trait TelegramApi { Media::Audio(audio) => { let mut new_audio = audio.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - - new_audio.media = FileUpload::String(attach_name); - - files.push(audio.media.to_form(&name)); - - if let Some(thumbnail) = &audio.thumbnail { + if audio.media.is_input() { let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); file_idx += 1; - new_audio.thumbnail = Some(FileUpload::String(attach_name)); + new_audio.media = FileUpload::String(format!("attach://{name}")); + files.push(audio.media.to_form_with_key(&name)); + } - files.push(thumbnail.to_form(&name)); - }; + if let Some(thumbnail) = &audio.thumbnail { + if thumbnail.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; + + new_audio.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(&name)); + } + } new_medias.push(Media::Audio(new_audio)); } @@ -281,24 +288,27 @@ pub trait TelegramApi { Media::Document(document) => { let mut new_document = document.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - new_document.media = FileUpload::String(attach_name); + if document.media.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push(document.media.to_form(&name)); + new_document.media = FileUpload::String(format!("attach://{name}")); + files.push(document.media.to_form_with_key(&name)); + } new_medias.push(Media::Document(new_document)); } + Media::Photo(photo) => { let mut new_photo = photo.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - new_photo.media = FileUpload::String(attach_name); + if photo.media.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push(photo.media.to_form(&name)); + new_photo.media = FileUpload::String(format!("attach://{name}")); + files.push(photo.media.to_form_with_key(&name)); + } new_medias.push(Media::Photo(new_photo)); } @@ -306,22 +316,24 @@ pub trait TelegramApi { Media::Video(video) => { let mut new_video = video.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); - file_idx += 1; - new_video.media = FileUpload::String(attach_name); - - files.push(video.media.to_form(&name)); - - if let Some(thumbnail) = &video.thumbnail { + if video.media.is_input() { let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); file_idx += 1; - new_video.thumbnail = Some(FileUpload::String(attach_name)); + new_video.media = FileUpload::String(format!("attach://{name}")); + files.push(video.media.to_form_with_key(&name)); + } + + if let Some(thumbnail) = &video.thumbnail { + if thumbnail.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - files.push(thumbnail.to_form(&name)); - }; + new_video.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(&name)); + } + } new_medias.push(Media::Video(new_video)); } @@ -341,10 +353,14 @@ pub trait TelegramApi { let method_name = "sendDocument"; let mut files: Vec = vec![]; - files.push(params.document.to_form("document")); + if params.document.is_input() { + files.push(params.document.to_form_with_key("document")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -354,10 +370,14 @@ pub trait TelegramApi { let method_name = "sendVideo"; let mut files: Vec = vec![]; - files.push(params.video.to_form("video")); + if params.video.is_input() { + files.push(params.video.to_form_with_key("video")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -370,10 +390,14 @@ pub trait TelegramApi { let method_name = "sendAnimation"; let mut files: Vec = vec![]; - files.push(params.animation.to_form("animation")); + if params.animation.is_input() { + files.push(params.animation.to_form_with_key("animation")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -381,11 +405,13 @@ pub trait TelegramApi { fn send_voice(&self, params: &SendVoiceParams) -> Result, Self::Error> { let method_name = "sendVoice"; - self.request_with_possible_form_data( - method_name, - params, - vec![params.voice.to_form("voice")], - ) + let mut files: Vec = vec![]; + + if params.voice.is_input() { + files.push(params.voice.to_form_with_key("voice")); + } + + self.request_with_possible_form_data(method_name, params, files) } fn send_video_note( @@ -395,10 +421,14 @@ pub trait TelegramApi { let method_name = "sendVideoNote"; let mut files: Vec = vec![]; - files.push(params.video_note.to_form("video_note")); + if params.video_note.is_input() { + files.push(params.video_note.to_form_with_key("video_note")); + } if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) @@ -579,7 +609,12 @@ pub trait TelegramApi { params: &SetChatPhotoParams, ) -> Result, Self::Error> { let photo = FileUpload::from(¶ms.photo); - self.request_with_form_data("setChatPhoto", params, vec![photo.to_form("photo")]) + + self.request_with_form_data( + "setChatPhoto", + params, + vec![photo.to_form_with_key("photo")], + ) } fn delete_chat_photo( @@ -864,20 +899,19 @@ pub trait TelegramApi { InputMedia::Animation(animation) => { let mut new_animation = animation.clone(); - let name = "animation".to_string(); - let attach_name = format!("attach://{name}"); - - new_animation.media = FileUpload::String(attach_name); - - files.push(animation.media.to_form(&name)); + if animation.media.is_input() { + let name = "animation"; + new_animation.media = FileUpload::String(format!("attach://{name}")); + files.push(animation.media.to_form_with_key(name)); + } if let Some(thumbnail) = &animation.thumbnail { - let name = "animation_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_animation.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "animation_thumb"; + new_animation.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Animation(new_animation) @@ -885,20 +919,19 @@ pub trait TelegramApi { InputMedia::Document(document) => { let mut new_document = document.clone(); - let name = "document".to_string(); - let attach_name = format!("attach://{name}"); - - new_document.media = FileUpload::String(attach_name); - - files.push(document.media.to_form(&name)); + if document.media.is_input() { + let name = "document"; + new_document.media = FileUpload::String(format!("attach://{name}")); + files.push(document.media.to_form_with_key(name)); + } if let Some(thumbnail) = &document.thumbnail { - let name = "document_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_document.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "document_thumb"; + new_document.thumbnail = + Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Document(new_document) @@ -906,20 +939,18 @@ pub trait TelegramApi { InputMedia::Audio(audio) => { let mut new_audio = audio.clone(); - let name = "audio".to_string(); - let attach_name = format!("attach://{name}"); - - new_audio.media = FileUpload::String(attach_name); - - files.push(audio.media.to_form(&name)); + if audio.media.is_input() { + let name = "audio"; + new_audio.media = FileUpload::String(format!("attach://{name}")); + files.push(audio.media.to_form_with_key(name)); + } if let Some(thumbnail) = &audio.thumbnail { - let name = "audio_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_audio.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "audio_thumb"; + new_audio.thumbnail = Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Audio(new_audio) @@ -927,32 +958,29 @@ pub trait TelegramApi { InputMedia::Photo(photo) => { let mut new_photo = photo.clone(); - let name = "photo".to_string(); - let attach_name = format!("attach://{name}"); - - new_photo.media = FileUpload::String(attach_name); - - files.push(photo.media.to_form(&name)); + if photo.media.is_input() { + let name = "photo"; + new_photo.media = FileUpload::String(format!("attach://{name}")); + files.push(photo.media.to_form_with_key(name)); + } InputMedia::Photo(new_photo) } InputMedia::Video(video) => { let mut new_video = video.clone(); - let name = "video".to_string(); - let attach_name = format!("attach://{name}"); - - new_video.media = FileUpload::String(attach_name); - - files.push(video.media.to_form(&name)); + if video.media.is_input() { + let name = "video"; + new_video.media = FileUpload::String(format!("attach://{name}")); + files.push(video.media.to_form_with_key(name)); + } if let Some(thumbnail) = &video.thumbnail { - let name = "video_thumb".to_string(); - let attach_name = format!("attach://{name}"); - - new_video.thumbnail = Some(FileUpload::String(attach_name)); - - files.push(thumbnail.to_form(&name)); + if thumbnail.is_input() { + let name = "video_thumb"; + new_video.thumbnail = Some(FileUpload::String(format!("attach://{name}"))); + files.push(thumbnail.to_form_with_key(name)); + } }; InputMedia::Video(new_video) @@ -995,11 +1023,13 @@ pub trait TelegramApi { params: &SendStickerParams, ) -> Result, Self::Error> { let method_name = "sendSticker"; - self.request_with_possible_form_data( - method_name, - params, - vec![params.sticker.to_form("sticker")], - ) + let mut files: Vec = vec![]; + + if params.sticker.is_input() { + files.push(params.sticker.to_form_with_key("sticker")); + } + + self.request_with_possible_form_data(method_name, params, files) } fn get_sticker_set( @@ -1017,7 +1047,7 @@ pub trait TelegramApi { self.request_with_form_data( "uploadStickerFile", params, - vec![sticker.to_form("sticker")], + vec![sticker.to_form_with_key("sticker")], ) } @@ -1028,16 +1058,19 @@ pub trait TelegramApi { let method_name = "createNewStickerSet"; let mut new_stickers: Vec = vec![]; let mut files: Vec = vec![]; + let mut file_idx = 0; - for (file_idx, sticker) in params.stickers.iter().enumerate() { + for sticker in ¶ms.stickers { let mut new_sticker = sticker.clone(); - let name = format!("file{file_idx}"); - let attach_name = format!("attach://{name}"); + if sticker.sticker.is_input() { + let name = format!("file{file_idx}"); + file_idx += 1; - new_sticker.sticker = FileUpload::String(attach_name); + new_sticker.sticker = FileUpload::String(format!("attach://{name}")); - files.push(sticker.sticker.to_form(&name)); + files.push(sticker.sticker.to_form_with_key(&name)); + } new_stickers.push(new_sticker); } @@ -1060,11 +1093,13 @@ pub trait TelegramApi { params: &AddStickerToSetParams, ) -> Result, Self::Error> { let method_name = "addStickerToSet"; - self.request_with_possible_form_data( - method_name, - params, - vec![params.sticker.sticker.to_form("sticker")], - ) + let mut files: Vec = vec![]; + + if params.sticker.sticker.is_input() { + files.push(params.sticker.sticker.to_form_with_key("sticker")); + } + + self.request_with_possible_form_data(method_name, params, files) } fn set_sticker_position_in_set( @@ -1124,7 +1159,9 @@ pub trait TelegramApi { let mut files: Vec = vec![]; if let Some(thumbnail) = ¶ms.thumbnail { - files.push(thumbnail.to_form("thumbnail")); + if thumbnail.is_input() { + files.push(thumbnail.to_form_with_key("thumbnail")); + } } self.request_with_possible_form_data(method_name, params, files) From 0d64bb235748a037552526eb4f78c1346ca79ab1 Mon Sep 17 00:00:00 2001 From: Roman Yusufkhanov Date: Sat, 27 Jul 2024 00:08:32 +0300 Subject: [PATCH 4/4] fix upload sticker file result --- src/api_traits/async_telegram_api.rs | 2 +- src/api_traits/telegram_api.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api_traits/async_telegram_api.rs b/src/api_traits/async_telegram_api.rs index f2943dd..65192dc 100644 --- a/src/api_traits/async_telegram_api.rs +++ b/src/api_traits/async_telegram_api.rs @@ -1095,7 +1095,7 @@ pub trait AsyncTelegramApi { async fn upload_sticker_file( &self, params: &UploadStickerFileParams, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let sticker = FileUpload::from(¶ms.sticker); self.request_with_form_data( diff --git a/src/api_traits/telegram_api.rs b/src/api_traits/telegram_api.rs index dd5a05f..a2a9ec0 100644 --- a/src/api_traits/telegram_api.rs +++ b/src/api_traits/telegram_api.rs @@ -1042,7 +1042,7 @@ pub trait TelegramApi { fn upload_sticker_file( &self, params: &UploadStickerFileParams, - ) -> Result, Self::Error> { + ) -> Result, Self::Error> { let sticker = FileUpload::from(¶ms.sticker); self.request_with_form_data( "uploadStickerFile",