pw_telegram_bot_raw_fork/types/
message.rs

1use serde::{Deserialize, Serialize};
2use serde::de::{Deserializer, Error};
3
4use crate::types::*;
5use crate::url::*;
6
7/// This object represents a chat message or a channel post.
8#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
9pub enum MessageOrChannelPost {
10    Message(Message),
11    ChannelPost(ChannelPost),
12}
13
14/// This object represents a chat message.
15#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
16pub struct Message {
17    /// Unique message identifier inside this chat.
18    pub id: MessageId,
19    /// Sender, can be empty for messages sent to channels.
20    pub from: User,
21    /// Date the message was sent in Unix time.
22    pub date: Integer,
23    /// Conversation the message belongs to.
24    pub chat: MessageChat,
25    /// Information about the original message.
26    pub forward: Option<Forward>,
27    /// For replies, the original message. Note that the Message object in this field will not
28    /// contain further reply_to_message fields even if it itself is a reply.
29    pub reply_to_message: Option<Box<MessageOrChannelPost>>,
30    /// Date the message was last edited in Unix time.
31    pub edit_date: Option<Integer>,
32    /// Kind of the message.
33    pub kind: MessageKind,
34}
35
36/// This object represents a channel message.
37#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
38pub struct ChannelPost {
39    /// Unique message identifier inside this chat.
40    pub id: MessageId,
41    /// Date the message was sent in Unix time.
42    pub date: Integer,
43    /// Conversation the message belongs to.
44    pub chat: Channel,
45    /// Information about the original message.
46    pub forward: Option<Forward>,
47    /// For replies, the original message. Note that the Message object in this field will not
48    /// contain further reply_to_message fields even if it itself is a reply.
49    pub reply_to_message: Option<Box<MessageOrChannelPost>>,
50    /// Date the message was last edited in Unix time.
51    pub edit_date: Option<Integer>,
52    /// Kind of the message.
53    pub kind: MessageKind,
54}
55
56/// Information about the original message.
57#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
58pub struct Forward {
59    /// Date the original message was sent in Unix time
60    pub date: Integer,
61    /// Sender of the original message.
62    pub from: ForwardFrom,
63}
64
65/// Information about the source of the original message.
66#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
67pub enum ForwardFrom {
68    /// Sender of the original message.
69    User {
70        /// Sender of the original message.
71        user: User,
72    },
73    /// For messages forwarded from a channel, information about the original channel.
74    Channel {
75        /// Original channel.
76        channel: Channel,
77        /// Identifier of the original message in the channel
78        message_id: Integer,
79    },
80    ChannelHiddenUser {
81        sender_name: String,
82    },
83    /// For messages forwarded from a hidden admin
84    HiddenGroupAdmin {
85        /// Original group
86        chat_id: SupergroupId,
87        /// Group title
88        title: String,
89    },
90}
91
92/// Kind of the message.
93#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
94pub enum MessageKind {
95    /// Text message.
96    Text {
97        /// Actual UTF-8 text of the message, 0-4096 characters.
98        data: String,
99        /// Special entities like usernames, URLs, bot commands, etc. that appear in the text
100        entities: Vec<MessageEntity>,
101    },
102    /// Message is an audio file.
103    Audio {
104        /// Information about the file.
105        data: Audio,
106    },
107    /// Message is a general file.
108    Document {
109        /// Information about the file.
110        data: Document,
111        /// Caption for the document, 0-200 characters.
112        caption: Option<String>,
113    },
114    /// Message is a photo.
115    Photo {
116        /// Available sizes of the photo.
117        data: Vec<PhotoSize>,
118        /// Caption for the photo, 0-200 characters.
119        caption: Option<String>,
120        /// The unique identifier of a media message group this message belongs to.
121        media_group_id: Option<String>,
122    },
123    /// Message is a sticker.
124    Sticker {
125        /// Information about the sticker.
126        data: Sticker,
127    },
128    /// Message is a video.
129    Video {
130        /// Information about the video.
131        data: Video,
132        /// Caption for the video, 0-200 characters.
133        caption: Option<String>,
134        /// The unique identifier of a media message group this message belongs to.
135        media_group_id: Option<String>,
136    },
137    /// Message is a voice message.
138    Voice {
139        /// Information about the file.
140        data: Voice,
141    },
142    /// Message is a video note.
143    VideoNote {
144        /// Information about the file.
145        data: VideoNote,
146    },
147    /// Message is a shared contact.
148    Contact {
149        /// Information about the contact.
150        data: Contact,
151    },
152    /// Message is a shared location.
153    Location {
154        /// Information about the location.
155        data: Location,
156    },
157    /// Message is a poll.
158    Poll {
159        /// Information about the poll.
160        data: Poll,
161    },
162    /// Message is a venue.
163    Venue {
164        /// Information about the venue.
165        data: Venue,
166    },
167    /// New members that were added to the group or supergroup and
168    /// information about them (the bot itself may be one of these members)
169    NewChatMembers {
170        /// Information about user (this member may be the bot itself).
171        data: Vec<User>,
172    },
173    /// A member was removed from the group.
174    LeftChatMember {
175        /// Information about user (this member may be the bot itself).
176        data: User,
177    },
178    /// New chat title.
179    NewChatTitle {
180        /// A chat title was changed to this value.
181        data: String,
182    },
183    /// New chat photo.
184    NewChatPhoto {
185        /// A chat photo was change to this value.
186        data: Vec<PhotoSize>,
187    },
188    /// Service message: the chat photo was deleted.
189    DeleteChatPhoto,
190    /// Service message: the group has been created.
191    GroupChatCreated,
192    /// Service message: the supergroup has been created. This field can‘t be received in a
193    /// message coming through updates, because bot can’t be a member of a supergroup when
194    /// it is created. It can only be found in reply_to_message if someone replies to a very
195    /// first message in a directly created supergroup.
196    SupergroupChatCreated,
197    /// Service message: the channel has been created. This field can‘t be received in a message
198    /// coming through updates, because bot can’t be a member of a channel when it is created.
199    /// It can only be found in reply_to_message if someone replies
200    /// to a very first message in a channel.
201    ChannelChatCreated,
202    /// The group has been migrated to a supergroup.
203    MigrateToChatId {
204        /// Supergroup chat identifier.
205        data: Integer,
206    },
207    /// The supergroup has been migrated from a group.
208    MigrateFromChatId {
209        /// Group chat identifier.
210        data: Integer,
211    },
212    /// Specified message was pinned.
213    PinnedMessage {
214        // Specified message was pinned. Note that the Message object in this field will not
215        // contain further reply_to_message fields even if it is itself a reply.
216        data: Box<MessageOrChannelPost>,
217    },
218    #[doc(hidden)]
219    Unknown { raw: RawMessage },
220}
221
222impl Message {
223    fn from_raw_message(raw: RawMessage) -> Result<Self, String> {
224        let id = raw.message_id;
225        let from = match raw.from.clone() {
226            Some(from) => from,
227            None => return Err(format!("Missing `from` field for Message")),
228        };
229        let date = raw.date;
230        let chat = match raw.chat.clone() {
231            Chat::Private(x) => MessageChat::Private(x),
232            Chat::Group(x) => MessageChat::Group(x),
233            Chat::Supergroup(x) => MessageChat::Supergroup(x),
234            Chat::Unknown(x) => MessageChat::Unknown(x),
235            Chat::Channel(_) => return Err(format!("Channel chat in Message")),
236        };
237
238        let reply_to_message = raw.reply_to_message.clone();
239        let edit_date = raw.edit_date;
240
241        let forward = match (
242            raw.forward_date,
243            &raw.forward_from,
244            &raw.forward_from_chat,
245            raw.forward_from_message_id,
246            &raw.forward_sender_name,
247        ) {
248            (None, &None, &None, None, &None) => None,
249            (Some(date), &Some(ref from), &None, None, &None) => Some(Forward {
250                date: date,
251                from: ForwardFrom::User { user: from.clone() },
252            }),
253            (Some(date), &None, &Some(Chat::Channel(ref channel)), Some(message_id), &None) => {
254                Some(Forward {
255                    date: date,
256                    from: ForwardFrom::Channel {
257                        channel: channel.clone(),
258                        message_id: message_id,
259                    },
260                })
261            }
262            (Some(date), &None, &None, None, &Some(ref sender_name)) => Some(Forward {
263                date,
264                from: ForwardFrom::ChannelHiddenUser {
265                    sender_name: sender_name.clone(),
266                },
267            }),
268            (
269                Some(date),
270                None,
271                Some(Chat::Supergroup(Supergroup {
272                                          id: chat_id, title, ..
273                                      })),
274                None,
275                None,
276            ) => Some(Forward {
277                date,
278                from: ForwardFrom::HiddenGroupAdmin {
279                    chat_id: chat_id.clone(),
280                    title: title.clone(),
281                },
282            }),
283            _ => return Err(format!("invalid forward fields combination")),
284        };
285
286        let make_message = |kind| {
287            Ok(Message {
288                id: id.into(),
289                from: from,
290                date: date,
291                chat: chat,
292                forward: forward,
293                reply_to_message: reply_to_message,
294                edit_date: edit_date,
295                kind: kind,
296            })
297        };
298
299        macro_rules! maybe_field {
300            ($name:ident, $variant:ident) => {{
301                if let Some(val) = raw.$name {
302                    return make_message(MessageKind::$variant { data: val });
303                }
304            }};
305        }
306
307        macro_rules! maybe_field_with_caption {
308            ($name:ident, $variant:ident) => {{
309                if let Some(val) = raw.$name {
310                    return make_message(MessageKind::$variant {
311                        data: val,
312                        caption: raw.caption,
313                    });
314                }
315            }};
316        }
317
318        macro_rules! maybe_field_with_caption_and_group {
319            ($name:ident, $variant:ident) => {{
320                if let Some(val) = raw.$name {
321                    return make_message(MessageKind::$variant {
322                        data: val,
323                        caption: raw.caption,
324                        media_group_id: raw.media_group_id,
325                    });
326                }
327            }};
328        }
329
330        macro_rules! maybe_true_field {
331            ($name:ident, $variant:ident) => {{
332                if let Some(True) = raw.$name {
333                    return make_message(MessageKind::$variant);
334                }
335            }};
336        }
337
338        if let Some(text) = raw.text {
339            let entities = raw.entities.unwrap_or_else(Vec::new);
340            return make_message(MessageKind::Text {
341                data: text,
342                entities: entities,
343            });
344        }
345
346        maybe_field!(audio, Audio);
347        maybe_field_with_caption!(document, Document);
348        maybe_field_with_caption_and_group!(photo, Photo);
349        maybe_field!(sticker, Sticker);
350        maybe_field_with_caption_and_group!(video, Video);
351        maybe_field!(voice, Voice);
352        maybe_field!(video_note, VideoNote);
353        maybe_field!(contact, Contact);
354        maybe_field!(location, Location);
355        maybe_field!(poll, Poll);
356        maybe_field!(venue, Venue);
357        maybe_field!(new_chat_members, NewChatMembers);
358        maybe_field!(left_chat_member, LeftChatMember);
359        maybe_field!(new_chat_title, NewChatTitle);
360        maybe_field!(new_chat_photo, NewChatPhoto);
361        maybe_true_field!(delete_chat_photo, DeleteChatPhoto);
362        maybe_true_field!(delete_chat_photo, DeleteChatPhoto);
363        maybe_true_field!(group_chat_created, GroupChatCreated);
364        maybe_true_field!(supergroup_chat_created, SupergroupChatCreated);
365        maybe_true_field!(channel_chat_created, ChannelChatCreated);
366        maybe_field!(migrate_to_chat_id, MigrateToChatId);
367        maybe_field!(migrate_from_chat_id, MigrateFromChatId);
368        maybe_field!(pinned_message, PinnedMessage);
369
370        make_message(MessageKind::Unknown { raw: raw })
371    }
372}
373
374impl<'de> Deserialize<'de> for Message {
375    fn deserialize<D>(deserializer: D) -> Result<Message, D::Error>
376        where
377            D: Deserializer<'de>,
378    {
379        let raw: RawMessage = Deserialize::deserialize(deserializer)?;
380
381        Self::from_raw_message(raw).map_err(|err| D::Error::custom(err))
382    }
383}
384
385impl ChannelPost {
386    fn from_raw_message(raw: RawMessage) -> Result<Self, String> {
387        let id = raw.message_id;
388        let date = raw.date;
389        let chat = match raw.chat.clone() {
390            Chat::Channel(channel) => channel,
391            _ => return Err(format!("Expected channel chat type for ChannelMessage")),
392        };
393        let reply_to_message = raw.reply_to_message.clone();
394        let edit_date = raw.edit_date;
395
396        let forward = match (
397            raw.forward_date,
398            &raw.forward_from,
399            &raw.forward_from_chat,
400            raw.forward_from_message_id,
401            &raw.forward_sender_name,
402        ) {
403            (None, &None, &None, None, &None) => None,
404            (Some(date), &Some(ref from), &None, None, &None) => Some(Forward {
405                date: date,
406                from: ForwardFrom::User { user: from.clone() },
407            }),
408            (Some(date), &None, &Some(Chat::Channel(ref channel)), Some(message_id), &None) => {
409                Some(Forward {
410                    date: date,
411                    from: ForwardFrom::Channel {
412                        channel: channel.clone(),
413                        message_id: message_id,
414                    },
415                })
416            }
417            (Some(date), &None, &None, None, &Some(ref sender_name)) => Some(Forward {
418                date,
419                from: ForwardFrom::ChannelHiddenUser {
420                    sender_name: sender_name.clone(),
421                },
422            }),
423            (
424                Some(date),
425                None,
426                Some(Chat::Supergroup(Supergroup {
427                                          id: chat_id, title, ..
428                                      })),
429                None,
430                None,
431            ) => Some(Forward {
432                date,
433                from: ForwardFrom::HiddenGroupAdmin {
434                    chat_id: chat_id.clone(),
435                    title: title.clone(),
436                },
437            }),
438            _ => return Err(format!("invalid forward fields combination")),
439        };
440
441        let make_message = |kind| {
442            Ok(ChannelPost {
443                id: id.into(),
444                date: date,
445                chat: chat,
446                forward: forward,
447                reply_to_message: reply_to_message,
448                edit_date: edit_date,
449                kind: kind,
450            })
451        };
452
453        macro_rules! maybe_field {
454            ($name:ident, $variant:ident) => {{
455                if let Some(val) = raw.$name {
456                    return make_message(MessageKind::$variant { data: val });
457                }
458            }};
459        }
460
461        macro_rules! maybe_field_with_caption {
462            ($name:ident, $variant:ident) => {{
463                if let Some(val) = raw.$name {
464                    return make_message(MessageKind::$variant {
465                        data: val,
466                        caption: raw.caption,
467                    });
468                }
469            }};
470        }
471
472        macro_rules! maybe_field_with_caption_and_group {
473            ($name:ident, $variant:ident) => {{
474                if let Some(val) = raw.$name {
475                    return make_message(MessageKind::$variant {
476                        data: val,
477                        caption: raw.caption,
478                        media_group_id: raw.media_group_id,
479                    });
480                }
481            }};
482        }
483
484        macro_rules! maybe_true_field {
485            ($name:ident, $variant:ident) => {{
486                if let Some(True) = raw.$name {
487                    return make_message(MessageKind::$variant);
488                }
489            }};
490        }
491
492        if let Some(text) = raw.text {
493            let entities = raw.entities.unwrap_or_else(Vec::new);
494            return make_message(MessageKind::Text {
495                data: text,
496                entities: entities,
497            });
498        }
499
500        maybe_field!(audio, Audio);
501        maybe_field_with_caption!(document, Document);
502        maybe_field_with_caption_and_group!(photo, Photo);
503        maybe_field!(sticker, Sticker);
504        maybe_field_with_caption_and_group!(video, Video);
505        maybe_field!(voice, Voice);
506        maybe_field!(video_note, VideoNote);
507        maybe_field!(contact, Contact);
508        maybe_field!(location, Location);
509        maybe_field!(poll, Poll);
510        maybe_field!(venue, Venue);
511        maybe_field!(new_chat_members, NewChatMembers);
512        maybe_field!(left_chat_member, LeftChatMember);
513        maybe_field!(new_chat_title, NewChatTitle);
514        maybe_field!(new_chat_photo, NewChatPhoto);
515        maybe_true_field!(delete_chat_photo, DeleteChatPhoto);
516        maybe_true_field!(delete_chat_photo, DeleteChatPhoto);
517        maybe_true_field!(group_chat_created, GroupChatCreated);
518        maybe_true_field!(supergroup_chat_created, SupergroupChatCreated);
519        maybe_true_field!(channel_chat_created, ChannelChatCreated);
520        maybe_field!(migrate_to_chat_id, MigrateToChatId);
521        maybe_field!(migrate_from_chat_id, MigrateFromChatId);
522        maybe_field!(pinned_message, PinnedMessage);
523
524        make_message(MessageKind::Unknown { raw: raw })
525    }
526}
527
528impl<'de> Deserialize<'de> for ChannelPost {
529    // TODO(knsd): Remove .clone()
530    fn deserialize<D>(deserializer: D) -> Result<ChannelPost, D::Error>
531        where
532            D: Deserializer<'de>,
533    {
534        let raw: RawMessage = Deserialize::deserialize(deserializer)?;
535
536        Self::from_raw_message(raw).map_err(|err| D::Error::custom(err))
537    }
538}
539
540impl<'de> Deserialize<'de> for MessageOrChannelPost {
541    // TODO(knsd): Remove .clone()
542    fn deserialize<D>(deserializer: D) -> Result<MessageOrChannelPost, D::Error>
543        where
544            D: Deserializer<'de>,
545    {
546        let raw: RawMessage = Deserialize::deserialize(deserializer)?;
547        let is_channel = match raw.chat {
548            Chat::Channel(_) => true,
549            _ => false,
550        };
551
552        let res = if is_channel {
553            ChannelPost::from_raw_message(raw).map(MessageOrChannelPost::ChannelPost)
554        } else {
555            Message::from_raw_message(raw).map(MessageOrChannelPost::Message)
556        };
557
558        res.map_err(|err| D::Error::custom(err))
559    }
560}
561
562/// This object represents a message. Directly mapped.
563#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
564pub struct RawMessage {
565    /// Unique message identifier inside this chat.
566    pub message_id: Integer,
567    /// Sender, can be empty for messages sent to channels.
568    pub from: Option<User>,
569    /// Date the message was sent in Unix time.
570    pub date: Integer,
571    /// Conversation the message belongs to.
572    pub chat: Chat,
573    /// For forwarded messages, sender of the original message.
574    pub forward_from: Option<User>,
575    /// For messages forwarded from a channel, information about the original channel.
576    pub forward_from_chat: Option<Chat>,
577    /// For forwarded channel posts, identifier of the original message in the channel.
578    pub forward_from_message_id: Option<Integer>,
579    /// For forwarded messages, date the original message was sent in Unix time.
580    pub forward_date: Option<Integer>,
581    /// For replies, the original message. Note that the Message object in this field will not
582    /// contain further reply_to_message fields even if it itself is a reply.
583    pub reply_to_message: Option<Box<MessageOrChannelPost>>,
584    /// Date the message was last edited in Unix time.
585    pub edit_date: Option<Integer>,
586    /// The unique identifier of a media message group this message belongs to.
587    pub media_group_id: Option<String>,
588    /// For text messages, the actual UTF-8 text of the message, 0-4096 characters.
589    pub text: Option<String>,
590    /// For text messages, special entities like usernames, URLs, bot commands, etc.
591    /// that appear in the text.
592    pub entities: Option<Vec<MessageEntity>>,
593    /// Message is an audio file, information about the file.
594    pub audio: Option<Audio>,
595    /// Message is a general file, information about the file.
596    pub document: Option<Document>,
597    // pub game: Option<Game>,
598    /// Message is a photo, available sizes of the photo.
599    pub photo: Option<Vec<PhotoSize>>,
600    /// Message is a sticker, information about the sticker.
601    pub sticker: Option<Sticker>,
602    /// Message is a video, information about the video.
603    pub video: Option<Video>,
604    /// Message is a voice message, information about the file.
605    pub voice: Option<Voice>,
606    /// Message is a video note message, information about the file.
607    pub video_note: Option<VideoNote>,
608    /// Caption for the document, photo or video, 0-200 characters.
609    pub caption: Option<String>,
610    /// Message is a shared contact, information about the contact.
611    pub contact: Option<Contact>,
612    /// Message is a shared location, information about the location.
613    pub location: Option<Location>,
614    /// Message is a native poll, information about the poll.
615    pub poll: Option<Poll>,
616    /// Message is a venue, information about the venue.
617    pub venue: Option<Venue>,
618    /// New members that were added to the group or supergroup and information
619    /// about them (the bot itself may be one of these members)
620    pub new_chat_members: Option<Vec<User>>,
621    /// A member was removed from the group, information about
622    /// them (this member may be the bot itself)
623    pub left_chat_member: Option<User>,
624    /// A chat title was changed to this value.
625    pub new_chat_title: Option<String>,
626    /// A chat photo was change to this value.
627    pub new_chat_photo: Option<Vec<PhotoSize>>,
628    /// Service message: the chat photo was deleted.
629    pub delete_chat_photo: Option<True>,
630    /// Service message: the group has been created.
631    pub group_chat_created: Option<True>,
632    /// Service message: the supergroup has been created. This field can‘t be received in a
633    /// message coming through updates, because bot can’t be a member of a supergroup when
634    /// it is created. It can only be found in reply_to_message if someone replies to a very
635    /// first message in a directly created supergroup.
636    pub supergroup_chat_created: Option<True>,
637    /// Service message: the channel has been created. This field can‘t be received in a message
638    /// coming through updates, because bot can’t be a member of a channel when it is created.
639    /// It can only be found in reply_to_message if someone replies
640    /// to a very first message in a channel.
641    pub channel_chat_created: Option<True>,
642    /// The group has been migrated to a supergroup with the specified identifier.
643    pub migrate_to_chat_id: Option<Integer>,
644    /// The supergroup has been migrated from a group with the specified identifier.
645    pub migrate_from_chat_id: Option<Integer>,
646    /// Specified message was pinned. Note that the Message object in this field will not contain
647    /// further reply_to_message fields even if it is itself a reply.
648    pub pinned_message: Option<Box<MessageOrChannelPost>>,
649    /// Forward from channel by a hidden user.
650    pub forward_sender_name: Option<String>,
651}
652
653/// This object represents one special entity in a text message.
654/// For example, hashtags, usernames, URLs, etc.
655#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
656pub struct MessageEntity {
657    /// Offset in UTF-16 code units to the start of the entity
658    pub offset: Integer,
659    /// Length of the entity in UTF-16 code units
660    pub length: Integer,
661    /// Kind of the entity.
662    pub kind: MessageEntityKind,
663}
664
665/// Kind of the entity.
666#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
667pub enum MessageEntityKind {
668    Mention,
669    Hashtag,
670    BotCommand,
671    Url,
672    Email,
673    Bold,
674    Italic,
675    Code,
676    Pre,
677    TextLink(String), // TODO(knsd) URL?
678    TextMention(User),
679    #[doc(hidden)]
680    Unknown(RawMessageEntity),
681}
682
683impl<'de> Deserialize<'de> for MessageEntity {
684    fn deserialize<D>(deserializer: D) -> Result<MessageEntity, D::Error>
685        where
686            D: Deserializer<'de>,
687    {
688        use self::MessageEntityKind::*;
689
690        let raw: RawMessageEntity = Deserialize::deserialize(deserializer)?;
691
692        let offset = raw.offset;
693        let length = raw.length;
694
695        macro_rules! required_field {
696            ($name:ident) => {{
697                match raw.$name {
698                    Some(val) => val,
699                    None => return Err(D::Error::missing_field(stringify!($name))),
700                }
701            }};
702        }
703
704        let kind = match raw.type_.as_str() {
705            "mention" => Mention,
706            "hashtag" => Hashtag,
707            "bot_command" => BotCommand,
708            "url" => Url,
709            "email" => Email,
710            "bold" => Bold,
711            "italic" => Italic,
712            "code" => Code,
713            "pre" => Pre,
714            "text_link" => TextLink(required_field!(url)),
715            "text_mention" => TextMention(required_field!(user)),
716            _ => Unknown(raw),
717        };
718
719        Ok(MessageEntity {
720            offset: offset,
721            length: length,
722            kind: kind,
723        })
724    }
725}
726
727/// This object represents one special entity in a text message.
728/// For example, hashtags, usernames, URLs, etc. Directly mapped.
729#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
730pub struct RawMessageEntity {
731    /// Type of the entity. Can be mention (@username), hashtag, bot_command, url, email,
732    /// bold (bold text), italic (italic text), code (monowidth string), pre (monowidth block),
733    /// text_link (for clickable text URLs), text_mention (for users without usernames).
734    #[serde(rename = "type")]
735    pub type_: String,
736    /// Offset in UTF-16 code units to the start of the entity.
737    pub offset: Integer,
738    /// Length of the entity in UTF-16 code units.
739    pub length: Integer,
740    /// For “text_link” only, url that will be opened after user taps on the text.
741    pub url: Option<String>,
742    /// For “text_mention” only, the mentioned user.
743    pub user: Option<User>,
744}
745
746/// This object represents one size of a photo or a file / sticker thumbnail.
747#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
748pub struct PhotoSize {
749    /// Unique identifier for this file.
750    pub file_id: String,
751    /// Photo width.
752    pub width: Integer,
753    /// Photo height.
754    pub height: Integer,
755    /// File size.
756    pub file_size: Option<Integer>,
757}
758
759/// This object represents an audio file to be treated as music by the Telegram clients.
760#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
761pub struct Audio {
762    /// Unique identifier for this file.
763    pub file_id: String,
764    /// Duration of the audio in seconds as defined by sender.
765    pub duration: Integer,
766    /// Performer of the audio as defined by sender or by audio tags.
767    pub performer: Option<String>,
768    /// Title of the audio as defined by sender or by audio tags.
769    pub title: Option<String>,
770    /// MIME type of the file as defined by sender.
771    pub mime_type: Option<String>,
772    /// File size.
773    pub file_size: Option<Integer>,
774}
775
776/// This object represents a general file (as opposed to photos, voice messages and audio files).
777#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
778pub struct Document {
779    /// Unique file identifier.
780    pub file_id: String,
781    /// Document thumbnail as defined by sender.
782    pub thumb: Option<PhotoSize>,
783    /// Original filename as defined by sender.
784    pub file_name: Option<String>,
785    /// MIME type of the file as defined by sender.
786    pub mime_type: Option<String>,
787    /// File size.
788    pub file_size: Option<Integer>,
789}
790
791/// This object represents a sticker.
792#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
793pub struct Sticker {
794    /// Identifier for this file, which can be used to download or reuse the file.
795    pub file_id: String,
796    /// Unique identifier for this file, which is supposed to be the same over time and for different bots.
797    /// Can't be used to download or reuse the file.
798    pub file_unique_id: String,
799    /// Sticker width.
800    pub width: Integer,
801    /// Sticker height.
802    pub height: Integer,
803    /// Sticker thumbnail in .webp or .jpg format.
804    pub thumb: Option<PhotoSize>,
805    /// Emoji associated with the sticker.
806    pub emoji: Option<String>,
807    /// The name of the sticker set this sticker belongs to.
808    pub set_name: Option<String>,
809    /// File size.
810    pub file_size: Option<Integer>,
811}
812
813/// This object represents a video file.
814#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
815pub struct Video {
816    /// Unique identifier for this file.
817    pub file_id: String,
818    /// Video width as defined by sender.
819    pub width: Integer,
820    /// Video height as defined by sender.
821    pub height: Integer,
822    /// Duration of the video in seconds as defined by sender.
823    pub duration: Integer,
824    /// Video thumbnail.
825    pub thumb: Option<PhotoSize>,
826    /// Mime type of a file as defined by sender.
827    pub mime_type: Option<String>,
828    /// File size.
829    pub file_size: Option<Integer>,
830}
831
832/// This object represents a voice note.
833#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
834pub struct Voice {
835    /// Unique identifier for this file.
836    pub file_id: String,
837    /// Duration of the audio in seconds as defined by sender.
838    pub duration: Integer,
839    /// MIME type of the file as defined by sender.
840    pub mime_type: Option<String>,
841    /// File size.
842    pub file_size: Option<Integer>,
843}
844
845/// This object represents a video message (available in Telegram apps as of v.4.0).
846#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
847pub struct VideoNote {
848    /// Unique identifier for this file.
849    pub file_id: String,
850    pub length: Integer,
851    /// Duration of the video in seconds as defined by sender.
852    pub duration: Integer,
853    /// Video thumbnail.
854    pub thumb: Option<PhotoSize>,
855    /// File size.
856    pub file_size: Option<Integer>,
857}
858
859/// This object represents a phone contact.
860#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
861pub struct Contact {
862    /// Contact's phone number.
863    pub phone_number: String,
864    /// Contact's first name.
865    pub first_name: String,
866    /// Contact's last name.
867    pub last_name: Option<String>,
868    /// Contact's user identifier in Telegram.
869    pub user_id: Option<Integer>,
870}
871
872/// This object represents a point on the map.
873#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
874pub struct Location {
875    /// Longitude as defined by sender.
876    pub longitude: Float,
877    /// Latitude as defined by sender.
878    pub latitude: Float,
879}
880
881/// This object represents a venue.
882#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
883pub struct Venue {
884    /// Venue location.
885    pub location: Location,
886    /// Name of the venue.
887    pub title: String,
888    /// Address of the venue.
889    pub address: String,
890    /// Foursquare identifier of the venue.
891    pub foursquare_id: Option<String>,
892}
893
894/// This object contains information about a poll.
895#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
896pub struct Poll {
897    /// Unique poll identifier.
898    pub id: String,
899    /// Poll question.
900    pub question: String,
901    /// List of poll options.
902    pub options: Vec<PollOption>,
903    /// Total number of users that voted in the poll.
904    pub total_voter_count: Integer,
905    /// True, if the poll is closed.
906    pub is_closed: bool,
907    /// True, if the poll is anonymous.
908    pub is_anonymous: bool,
909    /// Poll type.
910    #[serde(rename = "type")]
911    pub type_: PollType,
912    /// True, if the poll allows multiple answers.
913    pub allows_multiple_answers: bool,
914    /// 0-based identifier of the correct answer option. Available only for polls in the quiz mode,
915    /// which are closed, or was sent (not forwarded) by the bot or to the private chat with the bot.
916    pub correct_option_id: Option<Integer>,
917    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll.
918    pub explanation: Option<String>,
919    /// Special entities like usernames, URLs, bot commands, etc. that appear in the explanation.
920    pub explanation_entities: Option<Vec<MessageEntity>>,
921    /// Amount of time in seconds the poll will be active after creation.
922    pub open_period: Option<Integer>,
923    /// Point in time (Unix timestamp) when the poll will be automatically closed.
924    pub close_date: Option<Integer>,
925}
926
927/// This object represents an answer of a user in a non-anonymous poll.
928#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
929pub struct PollAnswer {
930    /// Unique poll identifier.
931    pub poll_id: String,
932    /// The user, who changed the answer to the poll.
933    pub user: User,
934    /// 0-based identifiers of answer options, chosen by the user. May be empty if the user retracted their vote.
935    pub option_ids: Vec<Integer>,
936}
937
938/// This object contains information about one answer option in a poll.
939#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
940pub struct PollOption {
941    /// Option text.
942    pub text: String,
943    /// Number of users that voted for this option.
944    pub voter_count: Integer,
945}
946
947/// Type of a poll.
948#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
949pub enum PollType {
950    #[serde(rename = "regular")]
951    Regular,
952    #[serde(rename = "quiz")]
953    Quiz,
954}
955
956/// This object represent a user's profile pictures.
957#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
958pub struct UserProfilePhotos {
959    /// Total number of profile pictures the target user has.
960    pub total_count: Integer,
961    /// Requested profile pictures (in up to 4 sizes each).
962    pub photos: Vec<Vec<PhotoSize>>,
963}
964
965/// This object represents a file ready to be downloaded.
966/// The file can be downloaded via the link `https://api.telegram.org/file/bot<token>/<file_path>`.
967/// It is guaranteed that the link will be valid for at least 1 hour.
968#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
969pub struct File {
970    /// Unique identifier for this file.
971    pub file_id: String,
972    /// File size, if known.
973    pub file_size: Option<Integer>,
974    /// File path. Use `https://api.telegram.org/file/bot<token>/<file_path>` to get the file.
975    pub file_path: Option<String>,
976}
977
978impl File {
979    pub fn get_url(&self, token: &str) -> Option<String> {
980        self.file_path
981            .as_ref()
982            .map(|path| format!("{}file/bot{}/{}", telegram_api_url(), token, path))
983    }
984}
985
986/// Strongly typed ParseMode.
987/// See [documentation](https://core.telegram.org/bots/api#formatting-options) for details.
988#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
989pub enum ParseMode {
990    /// Use legacy markdown formatting.
991    Markdown,
992    /// Use MarkdownV2 formatting.
993    MarkdownV2,
994    /// Use HTML formatting.
995    #[serde(rename = "HTML")]
996    Html,
997}
998
999impl ::std::fmt::Display for ParseMode {
1000    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
1001        match *self {
1002            ParseMode::Markdown => write!(f, "Markdown"),
1003            ParseMode::MarkdownV2 => write!(f, "MarkdownV2"),
1004            ParseMode::Html => write!(f, "HTML"),
1005        }
1006    }
1007}