use serde::{Deserialize, Serialize};
use crate::{
api::{Form, Method, Payload, PayloadError, WriteForm},
types::{
ChatId,
InputPaidMediaData,
InputPaidMediaGroup,
InputTextCaption,
Integer,
LivePhoto,
Message,
PhotoSize,
ReplyMarkup,
ReplyParameters,
SuggestedPostParameters,
User,
Video,
},
};
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct PaidMediaPurchased {
pub from: User,
#[serde(rename = "paid_media_payload")]
pub payload: String,
}
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct PaidMediaInfo {
pub star_count: Integer,
pub paid_media: Vec<PaidMedia>,
}
#[derive(Clone, Debug, derive_more::From, Deserialize, PartialEq, PartialOrd, Serialize)]
#[serde(from = "RawPaidMedia", into = "RawPaidMedia")]
pub enum PaidMedia {
LivePhoto(LivePhoto),
Photo(Vec<PhotoSize>),
Preview(PaidMediaPreview),
#[from(Video)]
Video(Box<Video>),
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, PartialEq, PartialOrd, Serialize)]
pub struct PaidMediaPreview {
pub duration: Option<Integer>,
pub height: Option<Integer>,
pub width: Option<Integer>,
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
#[serde(rename_all = "snake_case", tag = "type")]
enum RawPaidMedia {
LivePhoto {
live_photo: LivePhoto,
},
Photo {
photo: Vec<PhotoSize>,
},
Preview {
duration: Option<Integer>,
height: Option<Integer>,
width: Option<Integer>,
},
Video {
video: Box<Video>,
},
}
impl From<RawPaidMedia> for PaidMedia {
fn from(value: RawPaidMedia) -> Self {
match value {
RawPaidMedia::LivePhoto { live_photo } => Self::LivePhoto(live_photo),
RawPaidMedia::Photo { photo } => Self::Photo(photo),
RawPaidMedia::Preview {
duration,
height,
width,
} => Self::Preview(PaidMediaPreview {
duration,
height,
width,
}),
RawPaidMedia::Video { video } => Self::Video(video),
}
}
}
impl From<PaidMedia> for RawPaidMedia {
fn from(value: PaidMedia) -> Self {
match value {
PaidMedia::LivePhoto(live_photo) => Self::LivePhoto { live_photo },
PaidMedia::Photo(photo) => Self::Photo { photo },
PaidMedia::Preview(PaidMediaPreview {
duration,
height,
width,
}) => Self::Preview {
duration,
height,
width,
},
PaidMedia::Video(video) => Self::Video { video },
}
}
}
#[derive(Debug)]
pub struct SendPaidMedia {
media: InputPaidMediaGroup,
parameters: SendPaidMediaParameters,
}
impl SendPaidMedia {
pub fn new<T>(chat_id: T, media: InputPaidMediaGroup, star_count: Integer) -> Self
where
T: Into<ChatId>,
{
Self {
media,
parameters: SendPaidMediaParameters {
chat_id: Some(chat_id.into()),
star_count: Some(star_count),
..Default::default()
},
}
}
pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
self.parameters.allow_paid_broadcast = Some(value);
self
}
pub fn with_business_connection_id<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.business_connection_id = Some(value.into());
self
}
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = Some(value.into());
self
}
pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
self.parameters.direct_messages_topic_id = Some(value);
self
}
pub fn with_disable_notification(mut self, value: bool) -> Self {
self.parameters.disable_notification = Some(value);
self
}
pub fn with_message_thread_id(mut self, value: Integer) -> Self {
self.parameters.message_thread_id = Some(value);
self
}
pub fn with_payload<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.payload = Some(value.into());
self
}
pub fn with_protect_content(mut self, value: bool) -> Self {
self.parameters.protect_content = Some(value);
self
}
pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Self {
self.parameters.reply_parameters = Some(value);
self
}
pub fn with_reply_markup<T>(mut self, value: T) -> Self
where
T: Into<ReplyMarkup>,
{
self.parameters.reply_markup = Some(value.into());
self
}
pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
self.parameters.show_caption_above_media = Some(value);
self
}
pub fn with_suggested_post_parameters(mut self, value: SuggestedPostParameters) -> Self {
self.parameters.suggested_post_parameters = Some(value);
self
}
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Default, Serialize)]
struct SendPaidMediaParameters {
chat_id: Option<ChatId>,
star_count: Option<Integer>,
allow_paid_broadcast: Option<bool>,
business_connection_id: Option<String>,
#[serde(flatten)]
caption: Option<InputTextCaption>,
direct_messages_topic_id: Option<Integer>,
disable_notification: Option<bool>,
media: Vec<InputPaidMediaData>,
message_thread_id: Option<Integer>,
payload: Option<String>,
protect_content: Option<bool>,
reply_parameters: Option<ReplyParameters>,
reply_markup: Option<ReplyMarkup>,
show_caption_above_media: Option<bool>,
suggested_post_parameters: Option<SuggestedPostParameters>,
}
impl Method for SendPaidMedia {
type Response = Message;
fn into_payload(self) -> Result<Payload, PayloadError> {
let Self { media, mut parameters } = self;
let mut form = Form::default();
parameters.media = media.write(&mut form);
parameters.serialize(&mut form)?;
Payload::form("sendPaidMedia", form)
}
}