tgbot/types/definitions/media/
paid.rs1use serde::{Deserialize, Serialize};
2
3use crate::{
4 api::{Form, Method, Payload},
5 types::{
6 ChatId,
7 InputPaidMediaGroup,
8 Integer,
9 Message,
10 ParseMode,
11 PhotoSize,
12 ReplyMarkup,
13 ReplyMarkupError,
14 ReplyParameters,
15 ReplyParametersError,
16 SuggestedPostParameters,
17 SuggestedPostParametersError,
18 TextEntities,
19 TextEntity,
20 TextEntityError,
21 User,
22 Video,
23 },
24};
25
26#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
28pub struct PaidMediaPurchased {
29 pub from: User,
31 #[serde(rename = "paid_media_payload")]
33 pub payload: String,
34}
35
36impl PaidMediaPurchased {
37 pub fn new<T>(from: User, payload: T) -> Self
44 where
45 T: Into<String>,
46 {
47 Self {
48 from,
49 payload: payload.into(),
50 }
51 }
52}
53
54#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
56pub struct PaidMediaInfo {
57 pub star_count: Integer,
59 pub paid_media: Vec<PaidMedia>,
61}
62
63impl PaidMediaInfo {
64 pub fn new<A, B>(star_count: Integer, paid_media: A) -> Self
71 where
72 A: IntoIterator<Item = B>,
73 B: Into<PaidMedia>,
74 {
75 Self {
76 star_count,
77 paid_media: paid_media.into_iter().map(Into::into).collect(),
78 }
79 }
80}
81
82#[derive(Clone, Debug, derive_more::From, Deserialize, PartialEq, PartialOrd, Serialize)]
84#[serde(from = "RawPaidMedia", into = "RawPaidMedia")]
85#[allow(clippy::large_enum_variant)]
86pub enum PaidMedia {
87 Photo(Vec<PhotoSize>),
89 Preview(PaidMediaPreview),
91 Video(Video),
93}
94
95#[serde_with::skip_serializing_none]
97#[derive(Clone, Debug, Default, Deserialize, PartialEq, PartialOrd, Serialize)]
98pub struct PaidMediaPreview {
99 pub duration: Option<Integer>,
101 pub height: Option<Integer>,
103 pub width: Option<Integer>,
105}
106
107impl PaidMediaPreview {
108 pub fn with_duration(mut self, value: Integer) -> Self {
114 self.duration = Some(value);
115 self
116 }
117
118 pub fn with_height(mut self, value: Integer) -> Self {
124 self.height = Some(value);
125 self
126 }
127
128 pub fn with_width(mut self, value: Integer) -> Self {
134 self.width = Some(value);
135 self
136 }
137}
138
139#[serde_with::skip_serializing_none]
140#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
141#[serde(rename_all = "snake_case", tag = "type")]
142#[allow(clippy::large_enum_variant)]
143enum RawPaidMedia {
144 Photo {
145 photo: Vec<PhotoSize>,
146 },
147 Preview {
148 duration: Option<Integer>,
149 height: Option<Integer>,
150 width: Option<Integer>,
151 },
152 Video {
153 video: Video,
154 },
155}
156
157#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
158struct RawPaidMediaPhoto {
159 photo: Vec<PhotoSize>,
160}
161
162#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
163struct RawPaidMediaVideo {
164 video: Video,
165}
166
167impl From<RawPaidMedia> for PaidMedia {
168 fn from(value: RawPaidMedia) -> Self {
169 match value {
170 RawPaidMedia::Photo { photo } => Self::Photo(photo),
171 RawPaidMedia::Preview {
172 duration,
173 height,
174 width,
175 } => Self::Preview(PaidMediaPreview {
176 duration,
177 height,
178 width,
179 }),
180 RawPaidMedia::Video { video } => Self::Video(video),
181 }
182 }
183}
184
185impl From<PaidMedia> for RawPaidMedia {
186 fn from(value: PaidMedia) -> Self {
187 match value {
188 PaidMedia::Photo(photo) => Self::Photo { photo },
189 PaidMedia::Preview(PaidMediaPreview {
190 duration,
191 height,
192 width,
193 }) => Self::Preview {
194 duration,
195 height,
196 width,
197 },
198 PaidMedia::Video(video) => Self::Video { video },
199 }
200 }
201}
202
203#[derive(Debug)]
205pub struct SendPaidMedia {
206 form: Form,
207}
208
209impl SendPaidMedia {
210 pub fn new<T>(chat_id: T, media: InputPaidMediaGroup, star_count: Integer) -> Self
218 where
219 T: Into<ChatId>,
220 {
221 let mut form: Form = media.into();
222 form.insert_field("chat_id", chat_id.into());
223 form.insert_field("star_count", star_count);
224 Self { form }
225 }
226
227 pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
235 self.form.insert_field("allow_paid_broadcast", value);
236 self
237 }
238
239 pub fn with_business_connection_id<T>(mut self, value: T) -> Self
246 where
247 T: Into<String>,
248 {
249 self.form.insert_field("business_connection_id", value.into());
250 self
251 }
252
253 pub fn with_caption<T>(mut self, value: T) -> Self
259 where
260 T: Into<String>,
261 {
262 self.form.insert_field("caption", value.into());
263 self
264 }
265
266 pub fn with_caption_entities<T>(mut self, value: T) -> Result<Self, TextEntityError>
272 where
273 T: IntoIterator<Item = TextEntity>,
274 {
275 let value = value.into_iter().collect::<TextEntities>().serialize()?;
276 self.form.insert_field("caption_entities", value);
277 self.form.remove_field("parse_mode");
278 Ok(self)
279 }
280
281 pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
287 self.form.insert_field("direct_messages_topic_id", value);
288 self
289 }
290
291 pub fn with_disable_notification(mut self, value: bool) -> Self {
299 self.form.insert_field("disable_notification", value);
300 self
301 }
302
303 pub fn with_parse_mode(mut self, value: ParseMode) -> Self {
309 self.form.insert_field("parse_mode", value);
310 self.form.remove_field("caption_entities");
311 self
312 }
313
314 pub fn with_payload<T>(mut self, value: T) -> Self
322 where
323 T: Into<String>,
324 {
325 self.form.insert_field("payload", value.into());
326 self
327 }
328
329 pub fn with_protect_content(mut self, value: bool) -> Self {
335 self.form.insert_field("protect_content", value);
336 self
337 }
338
339 pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Result<Self, ReplyParametersError> {
345 let value = value.serialize()?;
346 self.form.insert_field("reply_parameters", value);
347 Ok(self)
348 }
349
350 pub fn with_reply_markup<T>(mut self, value: T) -> Result<Self, ReplyMarkupError>
356 where
357 T: Into<ReplyMarkup>,
358 {
359 let value = value.into().serialize()?;
360 self.form.insert_field("reply_markup", value);
361 Ok(self)
362 }
363
364 pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
370 self.form.insert_field("show_caption_above_media", value);
371 self
372 }
373
374 pub fn with_suggested_post_parameters(
384 mut self,
385 value: &SuggestedPostParameters,
386 ) -> Result<Self, SuggestedPostParametersError> {
387 let value = serde_json::to_string(value).map_err(SuggestedPostParametersError::Serialize)?;
388 self.form.insert_field("suggested_post_parameters", value);
389 Ok(self)
390 }
391}
392
393impl Method for SendPaidMedia {
394 type Response = Message;
395
396 fn into_payload(self) -> Payload {
397 Payload::form("sendPaidMedia", self.form)
398 }
399}