1use std::{collections::HashSet, time::Duration};
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value as JsonValue;
5
6use crate::{
7 api::{Method, Payload},
8 types::{
9 BusinessConnection,
10 BusinessMessagesDeleted,
11 CallbackQuery,
12 Chat,
13 ChatBoostRemoved,
14 ChatBoostUpdated,
15 ChatJoinRequest,
16 ChatMemberUpdated,
17 ChatPeerId,
18 ChatUsername,
19 ChosenInlineResult,
20 InlineQuery,
21 Integer,
22 MaybeInaccessibleMessage,
23 Message,
24 MessageReactionCountUpdated,
25 MessageReactionUpdated,
26 PaidMediaPurchased,
27 Poll,
28 PollAnswer,
29 PollAnswerVoter,
30 PreCheckoutQuery,
31 ShippingQuery,
32 User,
33 UserPeerId,
34 UserUsername,
35 },
36};
37
38#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
40pub struct Update {
41 #[serde(rename = "update_id")]
50 pub id: Integer,
51 #[serde(flatten)]
53 pub update_type: UpdateType,
54}
55
56impl Update {
57 pub fn new(id: Integer, update_type: UpdateType) -> Self {
64 Self { id, update_type }
65 }
66
67 pub fn get_chat(&self) -> Option<&Chat> {
69 self.get_message().map(|msg| &msg.chat).or(match self.update_type {
70 UpdateType::BotStatus(ref x) | UpdateType::UserStatus(ref x) => Some(&x.chat),
71 UpdateType::DeletedBusinessMessages(ref x) => Some(&x.chat),
72 UpdateType::ChatBoostRemoved(ref x) => Some(&x.chat),
73 UpdateType::ChatBoostUpdated(ref x) => Some(&x.chat),
74 UpdateType::ChatJoinRequest(ref x) => Some(&x.chat),
75 UpdateType::MessageReaction(ref x) => Some(&x.chat),
76 UpdateType::MessageReactionCount(ref x) => Some(&x.chat),
77 _ => None,
78 })
79 }
80
81 pub fn get_chat_id(&self) -> Option<ChatPeerId> {
83 self.get_chat().map(|chat| chat.get_id())
84 }
85
86 pub fn get_chat_username(&self) -> Option<&ChatUsername> {
88 self.get_chat().and_then(|chat| chat.get_username())
89 }
90
91 pub fn get_user(&self) -> Option<&User> {
93 Some(match self.update_type {
94 UpdateType::BotStatus(ref x) | UpdateType::UserStatus(ref x) => &x.from,
95 UpdateType::BusinessConnection(ref x) => &x.user,
96 UpdateType::CallbackQuery(ref x) => &x.from,
97 UpdateType::ChatBoostRemoved(_) => return None,
98 UpdateType::ChatBoostUpdated(_) => return None,
99 UpdateType::ChatJoinRequest(ref x) => &x.from,
100 UpdateType::ChosenInlineResult(ref x) => &x.from,
101 UpdateType::DeletedBusinessMessages(_) => return None,
102 UpdateType::InlineQuery(ref x) => &x.from,
103 UpdateType::Message(ref x)
104 | UpdateType::BusinessMessage(ref x)
105 | UpdateType::EditedBusinessMessage(ref x)
106 | UpdateType::EditedMessage(ref x)
107 | UpdateType::ChannelPost(ref x)
108 | UpdateType::EditedChannelPost(ref x) => return x.sender.get_user(),
109 UpdateType::MessageReaction(ref x) => return x.user.as_ref(),
110 UpdateType::MessageReactionCount(_) => return None,
111 UpdateType::Poll(_) => return None,
112 UpdateType::PollAnswer(ref x) => match &x.voter {
113 PollAnswerVoter::User(x) => x,
114 PollAnswerVoter::Chat(_) => return None,
115 },
116 UpdateType::PreCheckoutQuery(ref x) => &x.from,
117 UpdateType::PurchasedPaidMedia(ref x) => &x.from,
118 UpdateType::ShippingQuery(ref x) => &x.from,
119 UpdateType::Unknown(_) => return None,
120 })
121 }
122
123 pub fn get_user_id(&self) -> Option<UserPeerId> {
125 self.get_user().map(|user| user.id)
126 }
127
128 pub fn get_user_username(&self) -> Option<&UserUsername> {
130 self.get_user().and_then(|user| user.username.as_ref())
131 }
132
133 pub fn get_message(&self) -> Option<&Message> {
135 match self.update_type {
136 UpdateType::Message(ref msg)
137 | UpdateType::BusinessMessage(ref msg)
138 | UpdateType::EditedBusinessMessage(ref msg)
139 | UpdateType::EditedMessage(ref msg)
140 | UpdateType::ChannelPost(ref msg)
141 | UpdateType::EditedChannelPost(ref msg) => Some(msg),
142 UpdateType::CallbackQuery(ref query) => match query.message {
143 Some(MaybeInaccessibleMessage::Message(ref msg)) => Some(msg),
144 _ => None,
145 },
146 _ => None,
147 }
148 }
149}
150
151#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
153#[allow(clippy::large_enum_variant)]
154#[serde(rename_all = "snake_case")]
155pub enum UpdateType {
156 #[serde(rename = "my_chat_member")]
161 BotStatus(ChatMemberUpdated),
162 BusinessConnection(BusinessConnection),
165 BusinessMessage(Message),
167 CallbackQuery(CallbackQuery),
169 ChannelPost(Message),
171 #[serde(rename = "removed_chat_boost")]
175 ChatBoostRemoved(ChatBoostRemoved),
176 #[serde(rename = "chat_boost")]
180 ChatBoostUpdated(ChatBoostUpdated),
181 ChatJoinRequest(ChatJoinRequest),
186 ChosenInlineResult(ChosenInlineResult),
193 DeletedBusinessMessages(BusinessMessagesDeleted),
195 EditedBusinessMessage(Message),
197 EditedChannelPost(Message),
199 EditedMessage(Message),
201 InlineQuery(InlineQuery),
205 Message(Message),
207 MessageReaction(MessageReactionUpdated),
215 MessageReactionCount(MessageReactionCountUpdated),
221 Poll(Poll),
225 PollAnswer(PollAnswer),
229 PreCheckoutQuery(PreCheckoutQuery),
233 PurchasedPaidMedia(PaidMediaPurchased),
235 ShippingQuery(ShippingQuery),
239 #[serde(rename = "chat_member")]
245 UserStatus(ChatMemberUpdated),
246 #[serde(untagged)]
251 Unknown(JsonValue),
252}
253
254pub struct UnexpectedUpdate(Update);
258
259impl From<UnexpectedUpdate> for Update {
260 fn from(value: UnexpectedUpdate) -> Self {
261 value.0
262 }
263}
264
265impl TryFrom<Update> for BusinessConnection {
266 type Error = UnexpectedUpdate;
267
268 fn try_from(value: Update) -> Result<Self, Self::Error> {
269 use self::UpdateType::*;
270 match value.update_type {
271 BusinessConnection(x) => Ok(x),
272 _ => Err(UnexpectedUpdate(value)),
273 }
274 }
275}
276
277impl TryFrom<Update> for BusinessMessagesDeleted {
278 type Error = UnexpectedUpdate;
279
280 fn try_from(value: Update) -> Result<Self, Self::Error> {
281 use self::UpdateType::*;
282 match value.update_type {
283 DeletedBusinessMessages(x) => Ok(x),
284 _ => Err(UnexpectedUpdate(value)),
285 }
286 }
287}
288
289impl TryFrom<Update> for ChatMemberUpdated {
290 type Error = UnexpectedUpdate;
291
292 fn try_from(value: Update) -> Result<Self, Self::Error> {
293 use self::UpdateType::*;
294 match value.update_type {
295 BotStatus(x) | UserStatus(x) => Ok(x),
296 _ => Err(UnexpectedUpdate(value)),
297 }
298 }
299}
300
301impl TryFrom<Update> for CallbackQuery {
302 type Error = UnexpectedUpdate;
303
304 fn try_from(value: Update) -> Result<Self, Self::Error> {
305 use self::UpdateType::*;
306 match value.update_type {
307 CallbackQuery(x) => Ok(x),
308 _ => Err(UnexpectedUpdate(value)),
309 }
310 }
311}
312
313impl TryFrom<Update> for ChatJoinRequest {
314 type Error = UnexpectedUpdate;
315
316 fn try_from(value: Update) -> Result<Self, Self::Error> {
317 use self::UpdateType::*;
318 match value.update_type {
319 ChatJoinRequest(x) => Ok(x),
320 _ => Err(UnexpectedUpdate(value)),
321 }
322 }
323}
324
325impl TryFrom<Update> for ChosenInlineResult {
326 type Error = UnexpectedUpdate;
327
328 fn try_from(value: Update) -> Result<Self, Self::Error> {
329 use self::UpdateType::*;
330 match value.update_type {
331 ChosenInlineResult(x) => Ok(x),
332 _ => Err(UnexpectedUpdate(value)),
333 }
334 }
335}
336
337impl TryFrom<Update> for InlineQuery {
338 type Error = UnexpectedUpdate;
339
340 fn try_from(value: Update) -> Result<Self, Self::Error> {
341 use self::UpdateType::*;
342 match value.update_type {
343 InlineQuery(x) => Ok(x),
344 _ => Err(UnexpectedUpdate(value)),
345 }
346 }
347}
348
349impl TryFrom<Update> for Message {
350 type Error = UnexpectedUpdate;
351
352 fn try_from(value: Update) -> Result<Self, Self::Error> {
353 use self::UpdateType::*;
354 match value.update_type {
355 BusinessMessage(x)
356 | EditedBusinessMessage(x)
357 | EditedChannelPost(x)
358 | EditedMessage(x)
359 | ChannelPost(x)
360 | Message(x) => Ok(x),
361 _ => Err(UnexpectedUpdate(value)),
362 }
363 }
364}
365
366impl TryFrom<Update> for Poll {
367 type Error = UnexpectedUpdate;
368
369 fn try_from(value: Update) -> Result<Self, Self::Error> {
370 use self::UpdateType::*;
371 match value.update_type {
372 Poll(x) => Ok(x),
373 _ => Err(UnexpectedUpdate(value)),
374 }
375 }
376}
377
378impl TryFrom<Update> for PollAnswer {
379 type Error = UnexpectedUpdate;
380
381 fn try_from(value: Update) -> Result<Self, Self::Error> {
382 use self::UpdateType::*;
383 match value.update_type {
384 PollAnswer(x) => Ok(x),
385 _ => Err(UnexpectedUpdate(value)),
386 }
387 }
388}
389
390impl TryFrom<Update> for PreCheckoutQuery {
391 type Error = UnexpectedUpdate;
392
393 fn try_from(value: Update) -> Result<Self, Self::Error> {
394 use self::UpdateType::*;
395 match value.update_type {
396 PreCheckoutQuery(x) => Ok(x),
397 _ => Err(UnexpectedUpdate(value)),
398 }
399 }
400}
401
402impl TryFrom<Update> for PaidMediaPurchased {
403 type Error = UnexpectedUpdate;
404
405 fn try_from(value: Update) -> Result<Self, Self::Error> {
406 use self::UpdateType::*;
407 match value.update_type {
408 PurchasedPaidMedia(x) => Ok(x),
409 _ => Err(UnexpectedUpdate(value)),
410 }
411 }
412}
413
414impl TryFrom<Update> for ShippingQuery {
415 type Error = UnexpectedUpdate;
416
417 fn try_from(value: Update) -> Result<Self, Self::Error> {
418 use self::UpdateType::*;
419 match value.update_type {
420 ShippingQuery(x) => Ok(x),
421 _ => Err(UnexpectedUpdate(value)),
422 }
423 }
424}
425
426#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
428#[serde(rename_all = "snake_case")]
429pub enum AllowedUpdate {
430 #[serde(rename = "my_chat_member")]
432 BotStatus,
433 BusinessConnection,
435 BusinessMessage,
437 CallbackQuery,
439 ChannelPost,
441 #[serde(rename = "removed_chat_boost")]
443 ChatBoostRemoved,
444 #[serde(rename = "chat_boost")]
446 ChatBoostUpdated,
447 ChatJoinRequest,
449 ChosenInlineResult,
451 DeletedBusinessMessages,
453 EditedBusinessMessage,
455 EditedChannelPost,
457 EditedMessage,
459 InlineQuery,
461 Message,
463 MessageReaction,
465 MessageReactionCount,
467 Poll,
469 PollAnswer,
471 PreCheckoutQuery,
473 PurchasedPaidMedia,
475 ShippingQuery,
477 #[serde(rename = "chat_member")]
479 UserStatus,
480}
481
482#[serde_with::skip_serializing_none]
483#[derive(Clone, Debug, Default, Serialize)]
485pub struct GetUpdates {
486 allowed_updates: Option<HashSet<AllowedUpdate>>,
487 limit: Option<Integer>,
488 offset: Option<Integer>,
489 timeout: Option<Integer>,
490}
491
492impl Method for GetUpdates {
493 type Response = Vec<Update>;
494
495 fn into_payload(self) -> Payload {
496 Payload::json("getUpdates", self)
497 }
498}
499
500impl GetUpdates {
501 pub fn add_allowed_update(mut self, value: AllowedUpdate) -> Self {
507 match self.allowed_updates {
508 Some(ref mut updates) => {
509 updates.insert(value);
510 }
511 None => {
512 let mut updates = HashSet::new();
513 updates.insert(value);
514 self.allowed_updates = Some(updates);
515 }
516 };
517 self
518 }
519
520 pub fn with_allowed_updates<T>(mut self, value: T) -> Self
534 where
535 T: IntoIterator<Item = AllowedUpdate>,
536 {
537 self.allowed_updates = Some(value.into_iter().collect());
538 self
539 }
540
541 pub fn with_limit(mut self, value: Integer) -> Self {
547 self.limit = Some(value);
548 self
549 }
550
551 pub fn with_offset(mut self, value: Integer) -> Self {
566 self.offset = Some(value);
567 self
568 }
569
570 pub fn with_timeout(mut self, value: Duration) -> Self {
577 self.timeout = Some(value.as_secs() as i64);
578 self
579 }
580}