use serde::{Deserialize, Serialize};
use crate::types::{InputFile, ParseMode};
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum InputMedia {
Photo(InputMediaPhoto),
Video(InputMediaVideo),
Animation(InputMediaAnimation),
Audio(InputMediaAudio),
Document(InputMediaDocument),
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct InputMediaPhoto {
pub media: InputFile,
pub caption: Option<String>,
pub parse_mode: Option<ParseMode>,
}
impl InputMediaPhoto {
pub fn new(media: InputFile) -> Self {
Self { media, caption: None, parse_mode: None }
}
pub fn media(mut self, val: InputFile) -> Self {
self.media = val;
self
}
pub fn caption<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.caption = Some(val.into());
self
}
pub fn parse_mode(mut self, val: ParseMode) -> Self {
self.parse_mode = Some(val);
self
}
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct InputMediaVideo {
pub media: InputFile,
pub thumb: Option<InputFile>,
pub caption: Option<String>,
pub parse_mode: Option<ParseMode>,
pub width: Option<u16>,
pub height: Option<u16>,
pub duration: Option<u16>,
pub supports_streaming: Option<bool>,
}
impl InputMediaVideo {
pub fn new(media: InputFile) -> Self {
Self {
media,
thumb: None,
caption: None,
parse_mode: None,
width: None,
height: None,
duration: None,
supports_streaming: None,
}
}
pub fn media(mut self, val: InputFile) -> Self {
self.media = val;
self
}
pub fn thumb(mut self, val: InputFile) -> Self {
self.thumb = Some(val);
self
}
pub fn caption<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.caption = Some(val.into());
self
}
pub fn parse_mode(mut self, val: ParseMode) -> Self {
self.parse_mode = Some(val);
self
}
pub fn width(mut self, val: u16) -> Self {
self.width = Some(val);
self
}
pub fn height(mut self, val: u16) -> Self {
self.height = Some(val);
self
}
pub fn duration(mut self, val: u16) -> Self {
self.duration = Some(val);
self
}
pub fn supports_streaming(mut self, val: bool) -> Self {
self.supports_streaming = Some(val);
self
}
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct InputMediaAnimation {
pub media: InputFile,
pub thumb: Option<InputFile>,
pub caption: Option<String>,
pub parse_mode: Option<ParseMode>,
pub width: Option<u16>,
pub height: Option<u16>,
pub duration: Option<u16>,
}
impl InputMediaAnimation {
pub fn new(media: InputFile) -> Self {
Self {
media,
thumb: None,
caption: None,
parse_mode: None,
width: None,
height: None,
duration: None,
}
}
pub fn media(mut self, val: InputFile) -> Self {
self.media = val;
self
}
pub fn thumb(mut self, val: InputFile) -> Self {
self.thumb = Some(val);
self
}
pub fn caption<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.caption = Some(val.into());
self
}
pub fn parse_mode(mut self, val: ParseMode) -> Self {
self.parse_mode = Some(val);
self
}
pub fn width(mut self, val: u16) -> Self {
self.width = Some(val);
self
}
pub fn height(mut self, val: u16) -> Self {
self.height = Some(val);
self
}
pub fn duration(mut self, val: u16) -> Self {
self.duration = Some(val);
self
}
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct InputMediaAudio {
pub media: InputFile,
pub thumb: Option<InputFile>,
pub caption: Option<String>,
pub parse_mode: Option<ParseMode>,
pub duration: Option<u16>,
pub performer: Option<String>,
pub title: Option<String>,
}
impl InputMediaAudio {
pub fn new(media: InputFile) -> Self {
Self {
media,
thumb: None,
caption: None,
parse_mode: None,
performer: None,
title: None,
duration: None,
}
}
pub fn media(mut self, val: InputFile) -> Self {
self.media = val;
self
}
pub fn thumb(mut self, val: InputFile) -> Self {
self.thumb = Some(val);
self
}
pub fn caption<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.caption = Some(val.into());
self
}
pub fn parse_mode(mut self, val: ParseMode) -> Self {
self.parse_mode = Some(val);
self
}
pub fn duration(mut self, val: u16) -> Self {
self.duration = Some(val);
self
}
pub fn performer<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.performer = Some(val.into());
self
}
pub fn title<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.title = Some(val.into());
self
}
}
#[serde_with_macros::skip_serializing_none]
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct InputMediaDocument {
pub media: InputFile,
pub thumb: Option<InputFile>,
pub caption: Option<String>,
pub parse_mode: Option<ParseMode>,
}
impl InputMediaDocument {
pub fn new(media: InputFile) -> Self {
Self { media, thumb: None, caption: None, parse_mode: None }
}
pub fn thumb(mut self, val: InputFile) -> Self {
self.thumb = Some(val);
self
}
pub fn caption<S>(mut self, val: S) -> Self
where
S: Into<String>,
{
self.caption = Some(val.into());
self
}
pub fn parse_mode(mut self, val: ParseMode) -> Self {
self.parse_mode = Some(val);
self
}
}
impl InputMedia {
pub fn media(&self) -> &InputFile {
match self {
InputMedia::Photo(InputMediaPhoto { media, .. })
| InputMedia::Document(InputMediaDocument { media, .. })
| InputMedia::Audio(InputMediaAudio { media, .. })
| InputMedia::Animation(InputMediaAnimation { media, .. })
| InputMedia::Video(InputMediaVideo { media, .. }) => media,
}
}
}
impl From<InputMedia> for InputFile {
fn from(media: InputMedia) -> InputFile {
match media {
InputMedia::Photo(InputMediaPhoto { media, .. })
| InputMedia::Document(InputMediaDocument { media, .. })
| InputMedia::Audio(InputMediaAudio { media, .. })
| InputMedia::Animation(InputMediaAnimation { media, .. })
| InputMedia::Video(InputMediaVideo { media, .. }) => media,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn photo_serialize() {
let expected_json = r#"{"type":"photo","media":"123456"}"#;
let photo = InputMedia::Photo(InputMediaPhoto {
media: InputFile::FileId(String::from("123456")),
caption: None,
parse_mode: None,
});
let actual_json = serde_json::to_string(&photo).unwrap();
assert_eq!(expected_json, actual_json);
}
#[test]
fn video_serialize() {
let expected_json = r#"{"type":"video","media":"123456"}"#;
let video = InputMedia::Video(InputMediaVideo {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
parse_mode: None,
width: None,
height: None,
duration: None,
supports_streaming: None,
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
}
#[test]
fn animation_serialize() {
let expected_json = r#"{"type":"animation","media":"123456"}"#;
let video = InputMedia::Animation(InputMediaAnimation {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
parse_mode: None,
width: None,
height: None,
duration: None,
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
}
#[test]
fn audio_serialize() {
let expected_json = r#"{"type":"audio","media":"123456"}"#;
let video = InputMedia::Audio(InputMediaAudio {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
parse_mode: None,
duration: None,
performer: None,
title: None,
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
}
#[test]
fn document_serialize() {
let expected_json = r#"{"type":"document","media":"123456"}"#;
let video = InputMedia::Document(InputMediaDocument {
media: InputFile::FileId(String::from("123456")),
thumb: None,
caption: None,
parse_mode: None,
});
let actual_json = serde_json::to_string(&video).unwrap();
assert_eq!(expected_json, actual_json);
}
}