use std::collections::HashMap;
use crate::{
chat::ChatId,
file::{File, InputFile, InputFileVariant, PhotoSize},
markup::ReplyMarkup,
message::Message,
FileMethod, JsonMethod, TelegramMethod,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
pub struct Sticker {
pub file_id: String,
pub file_unique_id: String,
pub width: u32,
pub height: u32,
pub is_animated: bool,
pub thumb: Option<PhotoSize>,
pub emoji: Option<String>,
pub set_name: Option<String>,
pub mask_position: Option<MaskPosition>,
pub file_size: Option<u32>,
}
#[derive(Debug, Deserialize)]
pub struct StickerSet {
pub name: String,
pub title: String,
pub is_animated: bool,
pub contains_masks: bool,
pub stickers: Vec<Sticker>,
pub thumb: Option<PhotoSize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MaskPosition {
pub point: MaskPoint,
pub x_shift: f32,
pub y_shift: f32,
pub scale: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum MaskPoint {
Forehead,
Eyes,
Mouth,
Chin,
}
#[derive(Clone, Serialize)]
pub struct SendSticker {
pub chat_id: ChatId,
pub sticker: InputFileVariant,
#[serde(skip_serializing_if = "Option::is_none")]
pub disable_notification: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reply_to_message_id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_sending_without_reply: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub reply_markup: Option<ReplyMarkup>,
#[serde(skip_serializing_if = "Option::is_none")]
pub protect_content: Option<bool>,
}
impl SendSticker {
pub fn new(chat_id: impl Into<ChatId>, sticker: impl Into<InputFileVariant>) -> Self {
Self {
chat_id: chat_id.into(),
sticker: sticker.into(),
disable_notification: None,
reply_to_message_id: None,
allow_sending_without_reply: None,
reply_markup: None,
protect_content: None,
}
}
pub fn disable_notification(self) -> Self {
Self {
disable_notification: Some(true),
..self
}
}
pub fn reply_to(self, message_id: i64) -> Self {
Self {
reply_to_message_id: Some(message_id),
..self
}
}
pub fn allow_sending_without_reply(self) -> Self {
Self {
allow_sending_without_reply: Some(true),
..self
}
}
pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
Self {
reply_markup: Some(markup.into()),
..self
}
}
pub fn protect_content(self) -> Self {
Self {
protect_content: Some(true),
..self
}
}
}
impl TelegramMethod for SendSticker {
type Response = Message;
fn name() -> &'static str {
"sendSticker"
}
}
impl JsonMethod for SendSticker {}
#[derive(Clone, Serialize)]
pub struct GetStickerSet {
pub name: String,
}
impl GetStickerSet {
pub fn new(name: impl Into<String>) -> Self {
Self { name: name.into() }
}
}
impl TelegramMethod for GetStickerSet {
type Response = StickerSet;
fn name() -> &'static str {
"getStickerSet"
}
}
impl JsonMethod for GetStickerSet {}
#[derive(Clone, Serialize)]
pub struct UploadStickerFile {
pub user_id: i64,
pub png_sticker: InputFile,
}
impl UploadStickerFile {
pub fn new(user_id: i64, png_sticker: InputFile) -> Self {
Self {
user_id,
png_sticker,
}
}
}
impl TelegramMethod for UploadStickerFile {
type Response = File;
fn name() -> &'static str {
"uploadStickerFile"
}
}
impl FileMethod for UploadStickerFile {
fn files(&self) -> Option<std::collections::HashMap<&str, &InputFile>> {
let mut map = HashMap::new();
map.insert("png_sticker", &self.png_sticker);
Some(map)
}
}
#[derive(Clone, Serialize)]
pub struct CreateNewStickerSet {
pub user_id: i64,
pub name: String,
pub title: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub png_sticker: Option<InputFileVariant>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tgs_sticker: Option<InputFile>,
pub emojis: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contains_masks: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mask_position: Option<MaskPosition>,
}
impl CreateNewStickerSet {
pub fn new_png(
user_id: i64,
name: impl Into<String>,
title: impl Into<String>,
emojis: impl Into<String>,
png_sticker: impl Into<InputFileVariant>,
) -> Self {
Self {
user_id,
name: name.into(),
title: title.into(),
png_sticker: Some(png_sticker.into()),
tgs_sticker: None,
emojis: emojis.into(),
contains_masks: None,
mask_position: None,
}
}
pub fn new_tgs(
user_id: i64,
name: impl Into<String>,
title: impl Into<String>,
emojis: impl Into<String>,
tgs_sticker: InputFile,
) -> Self {
Self {
user_id,
name: name.into(),
title: title.into(),
png_sticker: None,
tgs_sticker: Some(tgs_sticker),
emojis: emojis.into(),
contains_masks: None,
mask_position: None,
}
}
pub fn with_masks(self) -> Self {
Self {
contains_masks: Some(true),
..self
}
}
pub fn with_mask_position(self, position: MaskPosition) -> Self {
Self {
mask_position: Some(position),
..self
}
}
}
impl TelegramMethod for CreateNewStickerSet {
type Response = bool;
fn name() -> &'static str {
"createNewStickerSet"
}
}
impl FileMethod for CreateNewStickerSet {
fn files(&self) -> Option<HashMap<&str, &InputFile>> {
let mut map = HashMap::new();
match (&self.png_sticker, &self.tgs_sticker) {
(None, Some(tgs)) => {
map.insert("tgs_sticker", tgs);
},
(Some(InputFileVariant::File(png)), None) => {
map.insert("png_sticker", png);
}
(Some(InputFileVariant::Id(_)), None) => {},
_ => panic!("exactly one of CreateNewStickerSet::png_sticker or CreateNewStickerSet::tgs_sticker can be used"),
}
Some(map)
}
}
#[derive(Clone, Serialize)]
pub struct AddStickerToSet {
pub user_id: i64,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub png_sticker: Option<InputFileVariant>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tgs_sticker: Option<InputFile>,
pub emojis: String,
pub mask_position: Option<MaskPosition>,
}
impl AddStickerToSet {
pub fn new_png(
user_id: i64,
name: impl Into<String>,
emojis: impl Into<String>,
png_sticker: impl Into<InputFileVariant>,
) -> Self {
Self {
user_id,
name: name.into(),
png_sticker: Some(png_sticker.into()),
tgs_sticker: None,
emojis: emojis.into(),
mask_position: None,
}
}
pub fn new_tgs(
user_id: i64,
name: impl Into<String>,
emojis: impl Into<String>,
tgs_sticker: InputFile,
) -> Self {
Self {
user_id,
name: name.into(),
png_sticker: None,
tgs_sticker: Some(tgs_sticker),
emojis: emojis.into(),
mask_position: None,
}
}
pub fn with_mask_position(self, position: MaskPosition) -> Self {
Self {
mask_position: Some(position),
..self
}
}
}
impl TelegramMethod for AddStickerToSet {
type Response = bool;
fn name() -> &'static str {
"addStickerToSet"
}
}
impl FileMethod for AddStickerToSet {
fn files(&self) -> Option<HashMap<&str, &InputFile>> {
let mut map = HashMap::new();
match (&self.png_sticker, &self.tgs_sticker) {
(None, Some(tgs)) => {
map.insert("tgs_sticker", tgs);
},
(Some(InputFileVariant::File(png)), None) => {
map.insert("png_sticker", png);
}
(Some(InputFileVariant::Id(_)), None) => {},
_ => panic!("exactly one of AddStickerToSet::png_sticker or AddStickerToSet::tgs_sticker can be used"),
}
Some(map)
}
}
#[derive(Clone, Serialize)]
pub struct SetStickerPositionInSet {
pub sticker: String,
pub position: usize,
}
impl SetStickerPositionInSet {
pub fn new(sticker: impl Into<String>, position: usize) -> Self {
Self {
sticker: sticker.into(),
position,
}
}
}
impl TelegramMethod for SetStickerPositionInSet {
type Response = bool;
fn name() -> &'static str {
"setStickerPositionInSet"
}
}
impl JsonMethod for SetStickerPositionInSet {}
#[derive(Clone, Serialize)]
pub struct DeleteStickerFromSet {
pub sticker: String,
}
impl DeleteStickerFromSet {
pub fn new(sticker: impl Into<String>) -> Self {
Self {
sticker: sticker.into(),
}
}
}
impl TelegramMethod for DeleteStickerFromSet {
type Response = bool;
fn name() -> &'static str {
"deleteStickerFromSet"
}
}
impl JsonMethod for DeleteStickerFromSet {}
#[derive(Clone, Serialize)]
pub struct SetStickerSetThumb {
pub name: String,
pub user_id: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub thumb: Option<InputFileVariant>,
}
impl SetStickerSetThumb {
pub fn new(name: impl Into<String>, user_id: i64) -> Self {
Self {
name: name.into(),
user_id,
thumb: None,
}
}
pub fn with_thumb(self, thumb: impl Into<InputFileVariant>) -> Self {
Self {
thumb: Some(thumb.into()),
..self
}
}
}
impl TelegramMethod for SetStickerSetThumb {
type Response = bool;
fn name() -> &'static str {
"setStickerSetThumb"
}
}
impl FileMethod for SetStickerSetThumb {
fn files(&self) -> Option<HashMap<&str, &InputFile>> {
if let Some(InputFileVariant::File(thumb)) = &self.thumb {
let mut map = HashMap::new();
map.insert("thumb", thumb);
Some(map)
} else {
None
}
}
}