Implement SendMediaGroup request

This commit is contained in:
Waffle 2019-09-07 22:15:57 +03:00
parent 27debb0c77
commit 7a2e8fd33b
4 changed files with 85 additions and 22 deletions

View file

@ -3,6 +3,7 @@ use serde::Serialize;
use crate::core::types::ParseMode;
use crate::core::requests::ChatId;
use crate::core::requests::utils;
use crate::core::types::InputMedia;
use std::path::PathBuf;
/// This is a convenient struct that builds `reqwest::r#async::multipart::Form`
@ -55,7 +56,7 @@ pub trait ToFormValue {
}
macro_rules! impl_for_struct {
($($name:ident),*) => {
($($name:ty),*) => {
$(
impl ToFormValue for $name {
fn to_form_value(&self) -> String {
@ -67,7 +68,7 @@ macro_rules! impl_for_struct {
}
impl_for_struct!(
bool, i32, i64
bool, i32, i64, Vec<InputMedia>
);
impl ToFormValue for str {

View file

@ -89,4 +89,5 @@ pub mod get_me;
pub mod send_message;
pub mod forward_message;
pub mod send_photo;
pub mod send_media_group;
mod utils;

View file

@ -1,46 +1,95 @@
use crate::core::{
types::{
Message, InputMedia,
},
network::{
request, ResponseResult,
},
types::{Message, InputMedia, InputFile},
network::request_multipart,
requests::{
form_builder::FormBuilder,
ChatId,
Request,
RequestInfo,
RequestContext,
RequestFuture,
ResponseResult,
}
};
use apply::Apply;
/// Use this method to send a group of photos or videos as an album.
#[derive(Debug, TypedBuilder)]
pub struct SendMediaGroup {
info: RequestInfo,
#[derive(Debug, Clone)]
pub struct SendMediaGroup<'a> {
ctx: RequestContext<'a>,
chat_id: ChatId,
media: Vec<InputMedia>,
pub chat_id: ChatId,
pub media: Vec<InputMedia>,
#[builder(default)]
disable_notification: Option<bool>,
#[builder(default)]
reply_to_message_id: Option<i64>,
pub disable_notification: Option<bool>,
pub reply_to_message_id: Option<i64>,
}
impl Request for SendMediaGroup {
impl<'a> Request<'a> for SendMediaGroup<'a> {
type ReturnValue = Vec<Message>;
fn send(self) -> RequestFuture<ResponseResult<Self::ReturnValue>> {
fn send(self) -> RequestFuture<'a, ResponseResult<Self::ReturnValue>> {
Box::pin(async move {
let params = FormBuilder::new()
.add("chat_id", &self.chat_id)
.apply(|form| {
self.media
.iter()
.map(|e| e.media())
.fold(form, |acc, file| {
if let InputFile::File(path) = file {
acc.add_file(
&path
.file_name()
.unwrap()
.to_string_lossy(),
path
)
} else {
acc
}
})
})
.add("media", &self.media)
.add_if_some("disable_notification", self.disable_notification.as_ref())
.add_if_some("reply_to_message_id", self.reply_to_message_id.as_ref())
.build();
request(&self.info.client, &self.info.token, "sendMediaGroup", Some(params)).await
request_multipart(&self.ctx.client, &self.ctx.token, "sendMediaGroup", Some(params)).await
})
}
}
impl<'a> SendMediaGroup<'a> {
pub(crate) fn new(
ctx: RequestContext<'a>,
chat_id: ChatId,
media: Vec<InputMedia>,
) -> Self {
SendMediaGroup {
ctx,
chat_id,
media,
disable_notification: None,
reply_to_message_id: None,
}
}
pub fn chat_id<T: Into<ChatId>>(mut self, val: T) -> Self {
self.chat_id = val.into();
self
}
pub fn media<T: Into<Vec<InputMedia>>>(mut self, val: T) -> Self {
self.media = val.into();
self
}
pub fn disable_notification<T: Into<bool>>(mut self, val: T) -> Self {
self.disable_notification = Some(val.into());
self
}
pub fn reply_to_message_id<T: Into<i64>>(mut self, val: T) -> Self {
self.reply_to_message_id = Some(val.into());
self
}
}

View file

@ -165,6 +165,18 @@ pub enum InputMedia {
},
}
impl InputMedia {
pub fn media(&self) -> &InputFile {
match self {
InputMedia::Photo { media, .. } |
InputMedia::Document { media, .. } |
InputMedia::Audio { media, .. } |
InputMedia::Animation { media, .. } |
InputMedia::Video { media, .. } => media,
}
}
}
#[cfg(test)]
mod tests {
use super::*;