rustigram_types/sticker.rs
1use crate::file::PhotoSize;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5/// A Telegram sticker.
6pub struct Sticker {
7 /// Telegram file identifier.
8 pub file_id: String,
9 /// Unique file identifier, stable across bots and time.
10 pub file_unique_id: String,
11 /// Sticker type.
12 #[serde(rename = "type")]
13 pub kind: StickerType,
14 /// Sticker width in pixels.
15 pub width: u32,
16 /// Sticker height in pixels.
17 pub height: u32,
18 /// `true` if the sticker is animated (TGS format).
19 pub is_animated: bool,
20 /// `true` if the sticker is a video sticker (WEBM format).
21 pub is_video: bool,
22 /// Sticker thumbnail.
23 pub thumbnail: Option<PhotoSize>,
24 /// Emoji associated with the sticker.
25 pub emoji: Option<String>,
26 /// Name of the sticker set this sticker belongs to.
27 pub set_name: Option<String>,
28 /// Premium animation for the sticker.
29 pub premium_animation: Option<crate::file::File>,
30 /// Mask position for mask stickers.
31 pub mask_position: Option<MaskPosition>,
32 /// Custom emoji identifier for custom emoji stickers.
33 pub custom_emoji_id: Option<String>,
34 /// `true` if the sticker must be repainted to a text color in messages.
35 pub needs_repainting: Option<bool>,
36 /// File size in bytes.
37 pub file_size: Option<u64>,
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(rename_all = "snake_case")]
42/// The type of sticker.
43pub enum StickerType {
44 /// A regular image sticker.
45 Regular,
46 /// A mask sticker (placed on photos).
47 Mask,
48 /// A custom emoji sticker.
49 CustomEmoji,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
53/// The position of a mask sticker on a face.
54pub struct MaskPosition {
55 /// The part of the face where the mask is placed.
56 pub point: MaskPoint,
57 /// Shift by X-axis measured in widths of the mask, scaled to the face size.
58 pub x_shift: f64,
59 /// Shift by Y-axis measured in heights of the mask, scaled to the face size.
60 pub y_shift: f64,
61 /// Mask scaling coefficient.
62 pub scale: f64,
63}
64
65#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
66#[serde(rename_all = "snake_case")]
67/// The specific point on a face where the mask is placed.
68pub enum MaskPoint {
69 /// Placed on the forehead.
70 Forehead,
71 /// Placed over the eyes.
72 Eyes,
73 /// Placed over the mouth.
74 Mouth,
75 /// Placed on the chin.
76 Chin,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
80/// A sticker set (collection of stickers).
81pub struct StickerSet {
82 /// Sticker set name.
83 pub name: String,
84 /// Sticker set title.
85 pub title: String,
86 /// Type of stickers in the set.
87 pub sticker_type: StickerType,
88 /// List of stickers in the set.
89 pub stickers: Vec<Sticker>,
90 /// Sticker set thumbnail.
91 pub thumbnail: Option<PhotoSize>,
92}
93
94/// Input sticker for creating or extending sticker sets.
95///
96/// `sticker` holds a `file_id`, HTTP URL, or `attach://<name>` reference.
97/// Raw bytes are handled at the API layer via multipart — this type is
98/// serialisable so it can be embedded in JSON request bodies.
99#[derive(Debug, Clone, Serialize, Deserialize)]
100pub struct InputSticker {
101 /// File identifier, URL, or `attach://<n>` reference.
102 pub sticker: String,
103 /// Format of the sticker.
104 pub format: StickerFormat,
105 /// List of 1–20 emoji associated with the sticker.
106 pub emoji_list: Vec<String>,
107 /// Mask position for mask stickers.
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub mask_position: Option<MaskPosition>,
110 /// List of 0–20 search keywords for the sticker.
111 #[serde(skip_serializing_if = "Option::is_none")]
112 pub keywords: Option<Vec<String>>,
113}
114
115impl InputSticker {
116 /// Creates an `InputSticker` from a `file_id` or URL.
117 pub fn new(
118 sticker: impl Into<String>,
119 format: StickerFormat,
120 emoji_list: Vec<impl Into<String>>,
121 ) -> Self {
122 Self {
123 sticker: sticker.into(),
124 format,
125 emoji_list: emoji_list.into_iter().map(Into::into).collect(),
126 mask_position: None,
127 keywords: None,
128 }
129 }
130 /// Sets the mask position for this sticker.
131 pub fn mask_position(mut self, mp: MaskPosition) -> Self {
132 self.mask_position = Some(mp);
133 self
134 }
135 /// Sets the search keywords for this sticker.
136 pub fn keywords(mut self, kw: Vec<impl Into<String>>) -> Self {
137 self.keywords = Some(kw.into_iter().map(Into::into).collect());
138 self
139 }
140}
141
142/// The encoding format of a sticker file.
143#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
144#[serde(rename_all = "snake_case")]
145pub enum StickerFormat {
146 /// A static WEBP sticker.
147 Static,
148 /// An animated TGS sticker.
149 Animated,
150 /// A video WEBM sticker.
151 Video,
152}