use crate::{
model::{ChatAdministratorRights, MenuButton},
utils::{
result::{Result, TelegramError},
FormDataFile,
},
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{fs::File, path::Path};
use telexide_proc_macros::build_struct;
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct GetUserProfilePhotos {
pub user_id: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i64>,
}
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct GetFile {
pub file_id: String,
}
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct AnswerCallbackQuery {
pub callback_query_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub show_alert: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_time: Option<i64>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(untagged)]
pub enum TrueOrObject<T> {
True(bool),
#[serde(bound(deserialize = "T: Deserialize<'de>"))]
Object(T),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum InputFile {
String(String),
File(FormDataFile),
}
impl InputFile {
pub fn new_file(file: &mut File, file_name: &str) -> Result<Self> {
Ok(Self::File(FormDataFile::new_from_file(file, file_name)?))
}
pub fn new(string: &str) -> Self {
Self::String(string.to_owned())
}
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self> {
let mut file = File::open(&path)?;
let file_name = path.as_ref().file_name().ok_or_else(|| {
TelegramError::InvalidArgument("file doesn't have a valid file name".to_owned())
})?;
Self::new_file(
&mut file,
file_name.to_str().ok_or_else(|| {
TelegramError::InvalidArgument("file doesn't have a valid file name".to_owned())
})?,
)
}
}
impl From<String> for InputFile {
fn from(string: String) -> Self {
Self::String(string)
}
}
impl From<&str> for InputFile {
fn from(string: &str) -> Self {
Self::String(string.to_owned())
}
}
impl From<FormDataFile> for InputFile {
fn from(file: FormDataFile) -> Self {
Self::File(file)
}
}
impl Serialize for InputFile {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Self::String(ref c) => serializer.serialize_str(c),
Self::File(ref c) => serializer.serialize_str(&format!(
"attach://{}",
&c.file_name
.as_ref()
.ok_or_else(|| serde::ser::Error::custom(
"file name doesn't exist for the InputFile file"
))?
)),
}
}
}
impl<'de> Deserialize<'de> for InputFile {
fn deserialize<D>(deserializer: D) -> std::result::Result<InputFile, D::Error>
where
D: Deserializer<'de>,
{
Ok(Self::String(Deserialize::deserialize(deserializer)?))
}
}
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct SetChatMenuButton {
#[serde(skip_serializing_if = "Option::is_none")]
pub chat_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub menu_button: Option<MenuButton>,
}
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct GetChatMenuButton {
#[serde(skip_serializing_if = "Option::is_none")]
pub chat_id: Option<i64>,
}
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct SetMyDefaultAdministratorRights {
#[serde(skip_serializing_if = "Option::is_none")]
pub rights: Option<ChatAdministratorRights>,
#[serde(skip_serializing_if = "Option::is_none")]
pub channels: Option<bool>,
}
#[build_struct]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct GetMyDefaultAdministratorRights {
#[serde(skip_serializing_if = "Option::is_none")]
pub channels: Option<bool>,
}