use serde::{Deserialize, Serialize};
use crate::{
api::{Form, WriteForm},
types::{Float, InputFile, InputTextCaption, Integer},
};
#[derive(Debug)]
pub struct InputMedia {
media_type: InputMediaType,
cover: Option<InputFile>,
media: Option<InputFile>,
parameters: InputMediaParameters,
photo: Option<InputFile>,
thumbnail: Option<InputFile>,
}
impl From<InputMediaAnimation> for InputMedia {
fn from(value: InputMediaAnimation) -> Self {
Self::new(InputMediaType::Animation, value.parameters)
.with_media(value.media)
.with_thumbnail(value.thumbnail)
}
}
impl From<InputMediaAudio> for InputMedia {
fn from(value: InputMediaAudio) -> Self {
Self::new(InputMediaType::Audio, value.parameters)
.with_media(value.media)
.with_thumbnail(value.thumbnail)
}
}
impl From<InputMediaDocument> for InputMedia {
fn from(value: InputMediaDocument) -> Self {
Self::new(InputMediaType::Document, value.parameters)
.with_media(value.media)
.with_thumbnail(value.thumbnail)
}
}
impl From<InputMediaLivePhoto> for InputMedia {
fn from(value: InputMediaLivePhoto) -> Self {
Self::new(InputMediaType::LivePhoto, value.parameters)
.with_media(value.media)
.with_photo(value.photo)
}
}
impl From<InputMediaLocation> for InputMedia {
fn from(value: InputMediaLocation) -> Self {
Self::new(InputMediaType::Location, value.parameters)
}
}
impl From<InputMediaPhoto> for InputMedia {
fn from(value: InputMediaPhoto) -> Self {
Self::new(InputMediaType::Photo, value.parameters).with_media(value.media)
}
}
impl From<InputMediaSticker> for InputMedia {
fn from(value: InputMediaSticker) -> Self {
Self::new(InputMediaType::Sticker, value.parameters).with_media(value.media)
}
}
impl From<InputMediaVenue> for InputMedia {
fn from(value: InputMediaVenue) -> Self {
Self::new(InputMediaType::Venue, value.parameters)
}
}
impl From<InputMediaVideo> for InputMedia {
fn from(value: InputMediaVideo) -> Self {
Self::new(InputMediaType::Video, value.parameters)
.with_cover(value.cover)
.with_media(value.media)
.with_thumbnail(value.thumbnail)
}
}
impl From<InputMediaVoiceNote> for InputMedia {
fn from(value: InputMediaVoiceNote) -> Self {
Self::new(InputMediaType::VoiceNote, value.parameters).with_media(value.media)
}
}
impl InputMedia {
pub fn link<T>(value: T) -> Self
where
T: Into<String>,
{
Self::new(
InputMediaType::Link,
InputMediaParameters {
url: Some(value.into()),
..Default::default()
},
)
}
fn new(media_type: InputMediaType, parameters: InputMediaParameters) -> Self {
Self {
media_type,
cover: None,
media: None,
parameters,
photo: None,
thumbnail: None,
}
}
fn with_cover(mut self, value: Option<InputFile>) -> Self {
self.cover = value;
self
}
fn with_media(mut self, value: InputFile) -> Self {
self.media = Some(value);
self
}
fn with_photo(mut self, value: InputFile) -> Self {
self.photo = Some(value);
self
}
fn with_thumbnail(mut self, value: Option<InputFile>) -> Self {
self.thumbnail = value;
self
}
}
impl WriteForm for InputMedia {
type Output = InputMediaData;
fn write(self, form: &mut Form) -> Self::Output {
let Self {
cover,
media,
media_type,
mut parameters,
photo,
thumbnail,
} = self;
parameters.cover = cover.map(|x| x.write(form));
parameters.media = media.map(|x| x.write(form));
parameters.photo = photo.map(|x| x.write(form));
parameters.thumbnail = thumbnail.map(|x| x.write(form));
InputMediaData { media_type, parameters }
}
}
#[derive(Debug)]
pub struct InputMediaAnimation {
parameters: InputMediaParameters,
media: InputFile,
thumbnail: Option<InputFile>,
}
impl<T> From<T> for InputMediaAnimation
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: Default::default(),
thumbnail: None,
}
}
}
impl InputMediaAnimation {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = Some(value.into());
self
}
pub fn with_duration(mut self, value: Integer) -> Self {
self.parameters.duration = Some(value);
self
}
pub fn with_has_spoiler(mut self, value: bool) -> Self {
self.parameters.has_spoiler = Some(value);
self
}
pub fn with_height(mut self, value: Integer) -> Self {
self.parameters.height = Some(value);
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_thumbnail<T>(mut self, value: T) -> Self
where
T: Into<InputFile>,
{
self.thumbnail = Some(value.into());
self
}
pub fn with_width(mut self, value: Integer) -> Self {
self.parameters.width = Some(value);
self
}
}
#[derive(Debug)]
pub struct InputMediaAudio {
media: InputFile,
parameters: InputMediaParameters,
thumbnail: Option<InputFile>,
}
impl<T> From<T> for InputMediaAudio
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: Default::default(),
thumbnail: None,
}
}
}
impl InputMediaAudio {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = Some(value.into());
self
}
pub fn with_duration(mut self, value: Integer) -> Self {
self.parameters.duration = Some(value);
self
}
pub fn with_performer<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.performer = Some(value.into());
self
}
pub fn with_thumbnail<T>(mut self, value: T) -> Self
where
T: Into<InputFile>,
{
self.thumbnail = Some(value.into());
self
}
pub fn with_title<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.title = Some(value.into());
self
}
}
#[derive(Debug)]
pub struct InputMediaDocument {
media: InputFile,
parameters: InputMediaParameters,
thumbnail: Option<InputFile>,
}
impl<T> From<T> for InputMediaDocument
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: Default::default(),
thumbnail: None,
}
}
}
impl InputMediaDocument {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = Some(value.into());
self
}
pub fn with_disable_content_type_detection(mut self, value: bool) -> Self {
self.parameters.disable_content_type_detection = Some(value);
self
}
pub fn with_thumbnail<T>(mut self, value: T) -> Self
where
T: Into<InputFile>,
{
self.thumbnail = Some(value.into());
self
}
}
#[derive(Debug)]
pub struct InputMediaLivePhoto {
media: InputFile,
photo: InputFile,
parameters: InputMediaParameters,
}
impl<A, B> From<(A, B)> for InputMediaLivePhoto
where
A: Into<InputFile>,
B: Into<InputFile>,
{
fn from((media, photo): (A, B)) -> Self {
Self {
media: media.into(),
photo: photo.into(),
parameters: Default::default(),
}
}
}
impl InputMediaLivePhoto {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = 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_has_spoiler(mut self, value: bool) -> Self {
self.parameters.has_spoiler = Some(value);
self
}
}
#[derive(Debug)]
pub struct InputMediaLocation {
parameters: InputMediaParameters,
}
impl InputMediaLocation {
pub fn new(latitude: Float, longitude: Float) -> Self {
Self {
parameters: InputMediaParameters {
latitude: Some(latitude),
longitude: Some(longitude),
..Default::default()
},
}
}
pub fn with_horizontal_accuracy(mut self, value: Float) -> Self {
self.parameters.horizontal_accuracy = Some(value);
self
}
}
#[derive(Debug)]
pub struct InputMediaPhoto {
media: InputFile,
parameters: InputMediaParameters,
}
impl<T> From<T> for InputMediaPhoto
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: Default::default(),
}
}
}
impl InputMediaPhoto {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = 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_has_spoiler(mut self, value: bool) -> Self {
self.parameters.has_spoiler = Some(value);
self
}
}
#[derive(Debug)]
pub struct InputMediaSticker {
media: InputFile,
parameters: InputMediaParameters,
}
impl<T> From<T> for InputMediaSticker
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: Default::default(),
}
}
}
impl InputMediaSticker {
pub fn with_emoji<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.emoji = Some(value.into());
self
}
}
#[derive(Debug)]
pub struct InputMediaVenue {
parameters: InputMediaParameters,
}
impl InputMediaVenue {
pub fn new<A, B>(latitude: Float, longitude: Float, title: A, address: B) -> Self
where
A: Into<String>,
B: Into<String>,
{
Self {
parameters: InputMediaParameters {
address: Some(address.into()),
latitude: Some(latitude),
longitude: Some(longitude),
title: Some(title.into()),
..Default::default()
},
}
}
pub fn with_foursquare_id<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.foursquare_id = Some(value.into());
self
}
pub fn with_foursquare_type<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.foursquare_type = Some(value.into());
self
}
pub fn with_google_place_id<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.google_place_id = Some(value.into());
self
}
pub fn with_google_place_type<T>(mut self, value: T) -> Self
where
T: Into<String>,
{
self.parameters.google_place_type = Some(value.into());
self
}
}
#[derive(Debug)]
pub struct InputMediaVideo {
media: InputFile,
parameters: InputMediaParameters,
cover: Option<InputFile>,
thumbnail: Option<InputFile>,
}
impl<T> From<T> for InputMediaVideo
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: InputMediaParameters::default(),
cover: None,
thumbnail: None,
}
}
}
impl InputMediaVideo {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = Some(value.into());
self
}
pub fn with_cover<T>(mut self, value: T) -> Self
where
T: Into<InputFile>,
{
self.cover = Some(value.into());
self
}
pub fn with_duration(mut self, value: Integer) -> Self {
self.parameters.duration = Some(value);
self
}
pub fn with_has_spoiler(mut self, value: bool) -> Self {
self.parameters.has_spoiler = Some(value);
self
}
pub fn with_height(mut self, value: Integer) -> Self {
self.parameters.height = Some(value);
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_start_timestamp(mut self, value: Integer) -> Self {
self.parameters.start_timestamp = Some(value);
self
}
pub fn with_supports_streaming(mut self, value: bool) -> Self {
self.parameters.supports_streaming = Some(value);
self
}
pub fn with_thumbnail<T>(mut self, value: T) -> Self
where
T: Into<InputFile>,
{
self.thumbnail = Some(value.into());
self
}
pub fn with_width(mut self, value: Integer) -> Self {
self.parameters.width = Some(value);
self
}
}
#[derive(Debug)]
pub struct InputMediaVoiceNote {
media: InputFile,
parameters: InputMediaParameters,
}
impl<T> From<T> for InputMediaVoiceNote
where
T: Into<InputFile>,
{
fn from(value: T) -> Self {
Self {
media: value.into(),
parameters: Default::default(),
}
}
}
impl InputMediaVoiceNote {
pub fn with_caption<T>(mut self, value: T) -> Self
where
T: Into<InputTextCaption>,
{
self.parameters.caption = Some(value.into());
self
}
pub fn with_duration(mut self, value: Integer) -> Self {
self.parameters.duration = Some(value);
self
}
}
#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct InputMediaData {
#[serde(rename = "type")]
media_type: InputMediaType,
#[serde(flatten)]
parameters: InputMediaParameters,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Default, Deserialize, Serialize)]
struct InputMediaParameters {
address: Option<String>,
#[serde(flatten)]
caption: Option<InputTextCaption>,
cover: Option<String>,
disable_content_type_detection: Option<bool>,
duration: Option<Integer>,
emoji: Option<String>,
foursquare_id: Option<String>,
foursquare_type: Option<String>,
google_place_id: Option<String>,
google_place_type: Option<String>,
has_spoiler: Option<bool>,
height: Option<Integer>,
horizontal_accuracy: Option<Float>,
latitude: Option<Float>,
longitude: Option<Float>,
media: Option<String>,
performer: Option<String>,
photo: Option<String>,
show_caption_above_media: Option<bool>,
start_timestamp: Option<Integer>,
supports_streaming: Option<bool>,
thumbnail: Option<String>,
title: Option<String>,
url: Option<String>,
width: Option<Integer>,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
enum InputMediaType {
Animation,
Audio,
Document,
Link,
LivePhoto,
Location,
Photo,
Sticker,
Venue,
Video,
VoiceNote,
}