use std::{
collections::HashMap,
fmt::{Display, Formatter, Result as FmtResult},
path::PathBuf,
};
use serde::Serialize;
use crate::network::NetworkTask;
#[derive(Debug, Clone)]
pub enum PhotoInput {
Url(String),
FilePath(PathBuf),
}
impl Display for PhotoInput {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
PhotoInput::Url(url) => write!(f, "[URL] {url}"),
PhotoInput::FilePath(path) => {
write!(f, "[File] {}", path.display())
}
}
}
}
#[derive(Debug, Clone, Serialize)]
pub struct PhotoMessage {
#[serde(skip_serializing)]
pub photo: PhotoInput,
#[serde(skip_serializing_if = "Option::is_none")]
pub caption: Option<String>,
}
impl PhotoMessage {
pub fn into_task(self, chat_id: String) -> NetworkTask {
let mut fields = HashMap::new();
fields.insert("chat_id".to_string(), chat_id);
fields.insert("parse_mode".to_string(), "MarkdownV2".to_string());
if let Some(caption) = self.caption {
fields.insert("caption".to_string(), caption);
}
match self.photo {
PhotoInput::FilePath(path) => {
let files = vec![(
path.to_string_lossy().into_owned(),
"photo".to_string(),
)];
NetworkTask::RequestMultipartWithFiles(fields, files)
}
PhotoInput::Url(url) => {
fields.insert("photo".to_string(), url);
NetworkTask::RequestMultipart(fields)
}
}
}
pub fn from_file(path: impl Into<PathBuf>) -> Self {
Self {
photo: PhotoInput::FilePath(path.into()),
caption: None,
}
}
pub fn from_url(url: impl Into<String>) -> Self {
Self {
photo: PhotoInput::Url(url.into()),
caption: None,
}
}
pub fn with_caption(mut self, caption: impl Into<String>) -> Self {
self.caption = Some(caption.into());
self
}
}
impl Display for PhotoMessage {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "PhotoMessage(photo: {}", self.photo)?;
if let Some(caption) = &self.caption {
write!(f, ", caption: {caption}")?;
}
write!(f, ")")
}
}