From 9bfec9546fe2a07c17e80862535f24f51c58a5ae Mon Sep 17 00:00:00 2001 From: jairinhohw Date: Tue, 24 Mar 2020 17:30:01 -0300 Subject: [PATCH] Add InputFile::Memory --- src/requests/form_builder.rs | 20 +++++++++++++++++++- src/requests/utils.rs | 4 ++++ src/types/input_file.rs | 16 ++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/requests/form_builder.rs b/src/requests/form_builder.rs index eeaa08d7..01092e68 100644 --- a/src/requests/form_builder.rs +++ b/src/requests/form_builder.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, path::PathBuf}; use reqwest::multipart::Form; use crate::{ - requests::utils::file_to_part, + requests::utils::{file_from_memory_to_part, file_to_part}, types::{ ChatId, InlineKeyboardMarkup, InputFile, InputMedia, MaskPosition, ParseMode, ReplyMarkup, @@ -33,6 +33,9 @@ impl FormBuilder { Self { form: self.form.text(name, string) } } Some(FormValue::File(path)) => self.add_file(name, path).await, + Some(FormValue::Memory(data)) => { + self.add_file_from_memory(name, data) + } None => self, } } @@ -50,6 +53,19 @@ impl FormBuilder { } } + fn add_file_from_memory<'a, N>(self, name: N, data: Vec) -> Self + where + N: Into>, + { + let name = name.into().into_owned(); + + Self { + form: self + .form + .part(name.clone(), file_from_memory_to_part(data, name)), + } + } + pub fn build(self) -> Form { self.form } @@ -57,6 +73,7 @@ impl FormBuilder { pub(crate) enum FormValue { File(PathBuf), + Memory(Vec), Str(String), } @@ -153,6 +170,7 @@ impl IntoFormValue for InputFile { fn into_form_value(&self) -> Option { match self { InputFile::File(path) => Some(FormValue::File(path.clone())), + InputFile::Memory(data) => Some(FormValue::Memory(data.clone())), InputFile::Url(url) => Some(FormValue::Str(url.clone())), InputFile::FileId(file_id) => Some(FormValue::Str(file_id.clone())), } diff --git a/src/requests/utils.rs b/src/requests/utils.rs index eab235ce..9ee2400d 100644 --- a/src/requests/utils.rs +++ b/src/requests/utils.rs @@ -34,3 +34,7 @@ pub async fn file_to_part(path_to_file: PathBuf) -> Part { Part::stream(Body::wrap_stream(file)).file_name(file_name) } + +pub fn file_from_memory_to_part(data: Vec, name: String) -> Part { + Part::bytes(data).file_name(name) +} diff --git a/src/types/input_file.rs b/src/types/input_file.rs index 8c6264a5..4d2d57ae 100644 --- a/src/types/input_file.rs +++ b/src/types/input_file.rs @@ -8,6 +8,7 @@ use std::path::PathBuf; #[derive(Clone, Debug, Eq, Hash, PartialEq, Deserialize)] pub enum InputFile { File(PathBuf), + Memory(Vec), Url(String), FileId(String), } @@ -20,6 +21,13 @@ impl InputFile { Self::File(path.into()) } + pub fn memory(data: D) -> Self + where + D: Into>, + { + Self::Memory(data.into()) + } + pub fn url(url: T) -> Self where T: Into, @@ -82,6 +90,14 @@ impl Serialize for InputFile { ), ) } + InputFile::Memory(data) => { + // NOTE: file should be actually attached with + // multipart/form-data + serializer.serialize_str(&format!( + "attach://{}", + String::from_utf8_lossy(data) + )) + } InputFile::Url(url) => serializer.serialize_str(url), InputFile::FileId(id) => serializer.serialize_str(id), }