Skip to main content

telegram_api_rs/
objects.rs

1//! This module contains all available types to use the Bot API</br>
2//! All types have functions to create them from_json
3//! ```ignore
4//! let user = User::from_json(json_data);
5//! ```
6//! or to turn them back into JSON-format
7//! ```ignore
8//! let json_data = user.to_json();
9//! ```
10//! as well as creating empty objects (having all fields filled with default data)
11//! ```ignore
12//! let user = User::empty()
13//! ```
14//! All types can also be displayed and cloned.
15
16extern crate json;
17extern crate rustc_serialize;
18
19use crate::*;
20use json::JsonValue;
21use std::fmt;
22
23#[derive(Debug, Clone, Copy)]
24pub enum MessageEntityType {
25    Mention,
26    Hashtag,
27    Cashtag,
28    BotCommand,
29    Url,
30    Email,
31    PhoneNumber,
32    Bold,
33    Italic,
34    Underline,
35    Strikethrough,
36    Code,
37    Pre,
38    TextLink,
39    TextMention,
40    Spoiler,
41    CustomEmoji,
42    Blockquote,
43    /// A type that was added to the Telegram protocol after this crate was last updated.
44    /// Received as an unrecognised string; treated as a no-op rather than a panic.
45    Unknown,
46}
47
48impl MessageEntityType {
49    fn from_string(s: String) -> MessageEntityType {
50        let s = s.as_str();
51        match s {
52            "mention" => MessageEntityType::Mention,
53            "hashtag" => MessageEntityType::Hashtag,
54            "cashtag" => MessageEntityType::Cashtag,
55            "bot_command" => MessageEntityType::BotCommand,
56            "url" => MessageEntityType::Url,
57            "email" => MessageEntityType::Email,
58            "phone_number" => MessageEntityType::PhoneNumber,
59            "bold" => MessageEntityType::Bold,
60            "italic" => MessageEntityType::Italic,
61            "underline" => MessageEntityType::Underline,
62            "strikethrough" => MessageEntityType::Strikethrough,
63            "code" => MessageEntityType::Code,
64            "pre" => MessageEntityType::Pre,
65            "text_link" => MessageEntityType::TextLink,
66            "text_mention" => MessageEntityType::TextMention,
67            "spoiler" => MessageEntityType::Spoiler,
68            "custom_emoji" => MessageEntityType::CustomEmoji,
69            "blockquote" => MessageEntityType::Blockquote,
70            _ => {
71                eprintln!(
72                    "objects::MessageEntityType::from_string: unknown type \"{}\", treating as Unknown",
73                    s
74                );
75                MessageEntityType::Unknown
76            }
77        }
78    }
79}
80
81impl fmt::Display for MessageEntityType {
82    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83        match self {
84            MessageEntityType::Mention => write!(f, "mention"),
85            MessageEntityType::Hashtag => write!(f, "hashtag"),
86            MessageEntityType::Cashtag => write!(f, "cashtag"),
87            MessageEntityType::BotCommand => write!(f, "bot_command"),
88            MessageEntityType::Url => write!(f, "url"),
89            MessageEntityType::Email => write!(f, "email"),
90            MessageEntityType::PhoneNumber => write!(f, "phone_number"),
91            MessageEntityType::Bold => write!(f, "bold"),
92            MessageEntityType::Italic => write!(f, "italic"),
93            MessageEntityType::Underline => write!(f, "underline"),
94            MessageEntityType::Strikethrough => write!(f, "strikethrough"),
95            MessageEntityType::Code => write!(f, "code"),
96            MessageEntityType::Pre => write!(f, "pre"),
97            MessageEntityType::TextLink => write!(f, "text_link"),
98            MessageEntityType::TextMention => write!(f, "text_mention"),
99            MessageEntityType::Spoiler => write!(f, "spoiler"),
100            MessageEntityType::CustomEmoji => write!(f, "custom_emoji"),
101            MessageEntityType::Blockquote => write!(f, "blockquote"),
102            MessageEntityType::Unknown => write!(f, "unknown"),
103        }
104    }
105}
106
107vec_to_json_array! {
108    vec_me_to_json_array(MessageEntity)
109    vec_i32_to_json_array(i32)
110    vec_string_to_json_array(String)
111    vec_po_to_json_array(PollOption)
112    vec_update_to_json_array(Update)
113    vec_user_to_json_array(User)
114    vec_photo_size_to_json_array(PhotoSize)
115    vec_sticker_to_json_array(Sticker)
116    vec_keyboard_button_to_json_array(KeyboardButton)
117    vec_inline_keyboard_button_to_json_array(InlineKeyboardButton)
118    vec_input_media_to_json_array(InputMedia)
119    vec_message_to_json_array(Message)
120    vec_chat_member_to_json_array(ChatMember)
121    vec_bot_command_to_json_array(BotCommand)
122}
123
124vec_vec_to_json_array! {
125    vec_vec_photo_size_to_json_array(PhotoSize, vec_photo_size_to_json_array)
126    vec_vec_keyboard_button_to_json_array(KeyboardButton, vec_keyboard_button_to_json_array)
127    vec_vec_inline_keyboard_button_to_json_array(InlineKeyboardButton, vec_inline_keyboard_button_to_json_array)
128}
129
130pub(crate) trait Custom {
131    fn from_json(s: JsonValue) -> Self;
132    fn create_json(j: JsonValue, v: Self, name: &'static str) -> JsonValue;
133    fn to_json(v: Self) -> JsonValue;
134    fn push(j: Vec<String>, v: Self, name: &'static str) -> Vec<String>;
135    fn default() -> Self;
136    fn url_encode(v: Self) -> String;
137}
138
139expand_custom_direct_i! {
140    impl Custom for i64 (as_i64, unwrap, 0)
141    impl Custom for i32 (as_i32, unwrap, 0)
142    impl Custom for f64 (as_f64, unwrap, 0.0)
143}
144
145expand_custom_vec! {
146    impl Custom for Vec<i32> (as_vec_i32, unwrap, [].to_vec(), vec_i32_to_json_array)
147    impl Custom for Vec<Update> (as_vec_update, unwrap, [].to_vec(), vec_update_to_json_array)
148    impl Custom for Vec<PollOption> (as_vec_poll_option, unwrap, [].to_vec(), vec_po_to_json_array)
149    impl Custom for Vec<User> (as_vec_user, unwrap, [].to_vec(), vec_user_to_json_array)
150    impl Custom for Vec<Sticker> (as_vec_sticker, unwrap, [].to_vec(), vec_sticker_to_json_array)
151    impl Custom for Vec<String> (as_vec_string, unwrap, [].to_vec(), vec_string_to_json_array)
152    impl Custom for Vec<MessageEntity> (as_vec_message_entity, unwrap, [].to_vec(), vec_me_to_json_array)
153    impl Custom for Vec<InputMedia> (as_vec_input_media, unwrap, [].to_vec(), vec_input_media_to_json_array)
154    impl Custom for Vec<Message> (as_vec_message, unwrap, [].to_vec(), vec_message_to_json_array)
155    impl Custom for Vec<ChatMember> (as_vec_chat_member, unwrap, [].to_vec(), vec_chat_member_to_json_array)
156    impl Custom for Vec<BotCommand> (as_vec_bot_command, unwrap, [].to_vec(), vec_bot_command_to_json_array)
157}
158
159expand_custom_vec_vec! {
160    impl Custom for Vec<Vec<PhotoSize>> (as_vec_vec_photo_size, unwrap, [].to_vec(), vec_vec_photo_size_to_json_array)
161    impl Custom for Vec<Vec<KeyboardButton>> (as_vec_vec_keyboard_button, unwrap, [].to_vec(), vec_vec_keyboard_button_to_json_array)
162    impl Custom for Vec<Vec<InlineKeyboardButton>> (as_vec_vec_inline_keyboard_button, unwrap, [].to_vec(), vec_vec_inline_keyboard_button_to_json_array)
163}
164
165expand_custom_direct_bool! {
166    impl Custom for bool (as_bool, unwrap, false)
167}
168
169expand_custom! {
170    impl Custom for String (to_string, clone, "".to_string())
171    impl Custom for MessageEntityType (as_message_entity_type, unwrap, MessageEntityType::Mention)
172}
173
174expand_custom_direct_object! {
175    impl Custom for Update (as_update, unwrap, Update::empty())
176    impl Custom for User (as_user, unwrap, User::empty())
177    impl Custom for Message (as_message, unwrap, Message::empty())
178    impl Custom for ChatInviteLink (as_chat_invite_link, unwrap, ChatInviteLink::empty())
179    impl Custom for ChatMember (as_chat_member, unwrap, ChatMember::empty())
180    impl Custom for Chat (as_chat, unwrap, Chat::empty())
181    impl Custom for Sticker (as_sticker, unwrap, Sticker::empty())
182    impl Custom for KeyboardButton (as_keyboard_button, unwrap, KeyboardButton::empty())
183    impl Custom for ReplyKeyboardMarkup (as_reply_keyboard_markup, unwrap, ReplyKeyboardMarkup::empty())
184    impl Custom for ReplyKeyboardRemove (as_reply_keyboard_remove, unwrap, ReplyKeyboardRemove::empty())
185    impl Custom for ForceReply (as_force_reply, unwrap, ForceReply::empty())
186    impl Custom for Location (as_location, unwrap, Location::empty())
187    impl Custom for PollOption (as_poll_option, unwrap, PollOption::empty())
188    impl Custom for MessageEntity (as_message_entity, unwrap, MessageEntity::empty())
189    impl Custom for PhotoSize (as_photo_size, unwrap, PhotoSize::empty())
190    impl Custom for InlineKeyboardMarkup (as_inline_keyboard_markup, unwrap, InlineKeyboardMarkup::empty())
191    impl Custom for InlineKeyboardButton (as_inline_keyboard_button, unwrap, InlineKeyboardButton::empty())
192    impl Custom for InputMedia (as_input_media, unwrap, InputMedia::empty())
193    impl Custom for UserProfilePhotos (as_user_profile_photos, unwrap, UserProfilePhotos::empty())
194    impl Custom for ChatPermissions (as_chat_permissions, unwrap, ChatPermissions::empty())
195    impl Custom for BotCommand (as_bot_command, unwrap, BotCommand::empty())
196    impl Custom for Poll (as_poll, unwrap, Poll::empty())
197    impl Custom for StickerSet (as_sticker_set, unwrap, StickerSet::empty())
198    impl Custom for MaskPosition (as_mask_position, unwrap, MaskPosition::empty())
199}
200
201expand_custom_option! {
202    impl Custom for Option<bool> (as_bool, unwrap, None)
203    impl Custom for Option<i32> (as_i32, unwrap, None)
204    impl Custom for Option<i64> (as_i64, unwrap, None)
205    impl Custom for Option<f64> (as_f64, unwrap, None)
206    impl Custom for Option<String> (to_string, clone, None)
207    impl Custom for Option<User> (as_user, unwrap, None)
208    impl Custom for Option<Message> (as_message, unwrap, None)
209    impl Custom for Option<InlineKeyboardMarkup> (as_inline_keyboard_markup, unwrap, None)
210    impl Custom for Option<VoiceChatStarted> (as_voice_chat_started, unwrap, None)
211    impl Custom for Option<VoiceChatEnded> (as_voice_chat_ended, unwrap, None)
212    impl Custom for Option<VoiceChatScheduled> (as_voice_chat_scheduled, unwrap, None)
213    impl Custom for Option<VoiceChatParticipantsInvited> (as_voice_chat_participants_invited, unwrap, None)
214    impl Custom for Option<ProximityAlertTriggered> (as_proximity_alert_triggered, unwrap, None)
215    impl Custom for Option<MessageAutoDeleteTimerChanged> (as_message_auto_delete_timer_changed, unwrap, None)
216    impl Custom for Option<PhotoSize> (as_photo_size, unwrap, None)
217    impl Custom for Option<Contact> (as_contact, unwrap, None)
218    impl Custom for Option<Dice> (as_dice, unwrap, None)
219    impl Custom for Option<Poll> (as_poll, unwrap, None)
220    impl Custom for Option<Venue> (as_venue, unwrap, None)
221    impl Custom for Option<ChatPermissions> (as_chat_permissions, unwrap, None)
222    impl Custom for Option<Location> (as_location, unwrap, None)
223    impl Custom for Option<Chat> (as_chat, unwrap, None)
224    impl Custom for Option<ChatPhoto> (as_chat_photo, unwrap, None)
225    impl Custom for Option<Animation> (as_animation, unwrap, None)
226    impl Custom for Option<Audio> (as_audio, unwrap, None)
227    impl Custom for Option<ChatInviteLink> (as_chat_invite_link, unwrap, None)
228    impl Custom for Option<ChatMember> (as_chat_member, unwrap, None)
229    impl Custom for Option<Document> (as_document, unwrap, None)
230    impl Custom for Option<LoginUrl> (as_login_url, unwrap, None)
231    impl Custom for Option<Sticker> (as_sticker, unwrap, None)
232    impl Custom for Option<Video> (as_video, unwrap, None)
233    impl Custom for Option<VideoNote> (as_video_note, unwrap, None)
234    impl Custom for Option<Voice> (as_voice, unwrap, None)
235    impl Custom for Option<MaskPosition> (as_mask_position, unwrap, None)
236    impl Custom for Option<KeyboardButtonPollType> (as_keyboard_button_poll_type, unwrap, None)
237    impl Custom for Option<ChatLocation> (as_chat_location, unwrap, None)
238    impl Custom for Option<CallbackQuery> (as_callback_query, unwrap, None)
239    impl Custom for Option<PollAnswer> (as_poll_answer, unwrap, None)
240    impl Custom for Option<ChatMemberUpdated> (as_chat_member_updated, unwrap, None)
241}
242
243expand_custom_box! {
244    impl Custom for Box<Chat> (as_box_chat, unwrap, Box::new(Chat::empty()))
245}
246
247expand_custom_option_box! {
248    impl Custom for Option<Box<Chat>> (as_box_chat, unwrap, None)
249    impl Custom for Option<Box<Message>> (as_box_message, unwrap, None)
250}
251
252expand_custom_option_vec! {
253    impl Custom for Option<Vec<MessageEntity>> (as_vec_message_entity, unwrap, None, vec_me_to_json_array)
254    impl Custom for Option<Vec<PhotoSize>> (as_vec_photo_size, unwrap, None, vec_photo_size_to_json_array)
255    impl Custom for Option<Vec<User>> (as_vec_user, unwrap, None, vec_user_to_json_array)
256}
257
258trait JsonExt {
259    fn as_update(&self) -> Option<Update>;
260    fn as_user(&self) -> Option<User>;
261    fn as_chat(&self) -> Option<Chat>;
262    fn as_message(&self) -> Option<Message>;
263    fn as_sticker(&self) -> Option<Sticker>;
264    fn as_keyboard_button_poll_type(&self) -> Option<KeyboardButtonPollType>;
265    fn as_keyboard_button(&self) -> Option<KeyboardButton>;
266    fn as_reply_keyboard_markup(&self) -> Option<ReplyKeyboardMarkup>;
267    fn as_reply_keyboard_remove(&self) -> Option<ReplyKeyboardRemove>;
268    fn as_force_reply(&self) -> Option<ForceReply>;
269    fn as_location(&self) -> Option<Location>;
270    fn as_poll_option(&self) -> Option<PollOption>;
271    fn as_message_entity(&self) -> Option<MessageEntity>;
272    fn as_photo_size(&self) -> Option<PhotoSize>;
273    fn as_mask_position(&self) -> Option<MaskPosition>;
274    fn as_inline_keyboard_markup(&self) -> Option<InlineKeyboardMarkup>;
275    fn as_inline_keyboard_button(&self) -> Option<InlineKeyboardButton>;
276    fn as_voice_chat_started(&self) -> Option<VoiceChatStarted>;
277    fn as_voice_chat_ended(&self) -> Option<VoiceChatEnded>;
278    fn as_voice_chat_scheduled(&self) -> Option<VoiceChatScheduled>;
279    fn as_voice_chat_participants_invited(&self) -> Option<VoiceChatParticipantsInvited>;
280    fn as_proximity_alert_triggered(&self) -> Option<ProximityAlertTriggered>;
281    fn as_message_auto_delete_timer_changed(&self) -> Option<MessageAutoDeleteTimerChanged>;
282    fn as_contact(&self) -> Option<Contact>;
283    fn as_dice(&self) -> Option<Dice>;
284    fn as_poll(&self) -> Option<Poll>;
285    fn as_venue(&self) -> Option<Venue>;
286    fn as_chat_permissions(&self) -> Option<ChatPermissions>;
287    fn as_chat_photo(&self) -> Option<ChatPhoto>;
288    fn as_chat_member(&self) -> Option<ChatMember>;
289    fn as_chat_location(&self) -> Option<ChatLocation>;
290    fn as_animation(&self) -> Option<Animation>;
291    fn as_audio(&self) -> Option<Audio>;
292    fn as_chat_invite_link(&self) -> Option<ChatInviteLink>;
293    fn as_document(&self) -> Option<Document>;
294    fn as_video(&self) -> Option<Video>;
295    fn as_video_note(&self) -> Option<VideoNote>;
296    fn as_voice(&self) -> Option<Voice>;
297    fn as_login_url(&self) -> Option<LoginUrl>;
298    fn as_callback_query(&self) -> Option<CallbackQuery>;
299    fn as_poll_answer(&self) -> Option<PollAnswer>;
300    fn as_chat_member_updated(&self) -> Option<ChatMemberUpdated>;
301    fn as_input_media(&self) -> Option<InputMedia>;
302    fn as_user_profile_photos(&self) -> Option<UserProfilePhotos>;
303    fn as_bot_command(&self) -> Option<BotCommand>;
304    fn as_sticker_set(&self) -> Option<StickerSet>;
305    fn as_vec_poll_option(&self) -> Option<Vec<PollOption>>;
306    fn as_vec_string(&self) -> Option<Vec<String>>;
307    fn as_vec_update(&self) -> Option<Vec<Update>>;
308    fn as_vec_user(&self) -> Option<Vec<User>>;
309    fn as_vec_photo_size(&self) -> Option<Vec<PhotoSize>>;
310    fn as_vec_sticker(&self) -> Option<Vec<Sticker>>;
311    fn as_vec_keyboard_button(&self) -> Option<Vec<KeyboardButton>>;
312    fn as_vec_inline_keyboard_button(&self) -> Option<Vec<InlineKeyboardButton>>;
313    fn as_vec_input_media(&self) -> Option<Vec<InputMedia>>;
314    fn as_vec_message(&self) -> Option<Vec<Message>>;
315    fn as_vec_chat_member(&self) -> Option<Vec<ChatMember>>;
316    fn as_vec_bot_command(&self) -> Option<Vec<BotCommand>>;
317    fn as_vec_vec_photo_size(&self) -> Option<Vec<Vec<PhotoSize>>>;
318    fn as_vec_vec_keyboard_button(&self) -> Option<Vec<Vec<KeyboardButton>>>;
319    fn as_vec_vec_inline_keyboard_button(&self) -> Option<Vec<Vec<InlineKeyboardButton>>>;
320    fn as_vec_i32(&self) -> Option<Vec<i32>>;
321    fn as_message_entity_type(&self) -> Option<MessageEntityType>;
322    fn as_vec_message_entity(&self) -> Option<Vec<MessageEntity>>;
323    fn as_box_chat(&self) -> Option<Box<Chat>>;
324    fn as_box_message(&self) -> Option<Box<Message>>;
325}
326
327impl JsonExt for JsonValue {
328    as_custom! {
329        fn as_update(&self) -> Option<Update>
330        fn as_user(&self) -> Option<User>
331        fn as_chat(&self) -> Option<Chat>
332        fn as_message(&self) -> Option<Message>
333        fn as_sticker(&self) -> Option<Sticker>
334        fn as_keyboard_button_poll_type(&self) -> Option<KeyboardButtonPollType>
335        fn as_keyboard_button(&self) -> Option<KeyboardButton>
336        fn as_reply_keyboard_markup(&self) -> Option<ReplyKeyboardMarkup>
337        fn as_reply_keyboard_remove(&self) -> Option<ReplyKeyboardRemove>
338        fn as_force_reply(&self) -> Option<ForceReply>
339        fn as_inline_keyboard_button(&self) -> Option<InlineKeyboardButton>
340        fn as_location(&self) -> Option<Location>
341        fn as_poll_option(&self) -> Option<PollOption>
342        fn as_photo_size(&self) -> Option<PhotoSize>
343        fn as_mask_position(&self) -> Option<MaskPosition>
344        fn as_message_entity(&self) -> Option<MessageEntity>
345        fn as_contact(&self) -> Option<Contact>
346        fn as_dice(&self) -> Option<Dice>
347        fn as_poll(&self) -> Option<Poll>
348        fn as_venue(&self) -> Option<Venue>
349        fn as_chat_permissions(&self) -> Option<ChatPermissions>
350        fn as_chat_photo(&self) -> Option<ChatPhoto>
351        fn as_chat_member(&self) -> Option<ChatMember>
352        fn as_chat_location(&self) -> Option<ChatLocation>
353        fn as_animation(&self) -> Option<Animation>
354        fn as_audio(&self) -> Option<Audio>
355        fn as_inline_keyboard_markup(&self) -> Option<InlineKeyboardMarkup>
356        fn as_voice_chat_started(&self) -> Option<VoiceChatStarted>
357        fn as_voice_chat_ended(&self) -> Option<VoiceChatEnded>
358        fn as_voice_chat_scheduled(&self) -> Option<VoiceChatScheduled>
359        fn as_voice_chat_participants_invited(&self) -> Option<VoiceChatParticipantsInvited>
360        fn as_proximity_alert_triggered(&self) -> Option<ProximityAlertTriggered>
361        fn as_message_auto_delete_timer_changed(&self) -> Option<MessageAutoDeleteTimerChanged>
362        fn as_chat_invite_link(&self) -> Option<ChatInviteLink>
363        fn as_document(&self) -> Option<Document>
364        fn as_video(&self) -> Option<Video>
365        fn as_video_note(&self) -> Option<VideoNote>
366        fn as_voice(&self) -> Option<Voice>
367        fn as_login_url(&self) -> Option<LoginUrl>
368        fn as_callback_query(&self) -> Option<CallbackQuery>
369        fn as_poll_answer(&self) -> Option<PollAnswer>
370        fn as_chat_member_updated(&self) -> Option<ChatMemberUpdated>
371        fn as_input_media(&self) -> Option<InputMedia>
372        fn as_user_profile_photos(&self) -> Option<UserProfilePhotos>
373        fn as_bot_command(&self) -> Option<BotCommand>
374        fn as_sticker_set(&self) -> Option<StickerSet>
375    }
376    as_vec_custom! {
377        fn as_vec_poll_option(&self) -> Option<Vec<PollOption>>
378        fn as_vec_update(&self) -> Option<Vec<Update>>
379        fn as_vec_user(&self) -> Option<Vec<User>>
380        fn as_vec_i32(&self) -> Option<Vec<i32>>
381        fn as_vec_string(&self) -> Option<Vec<String>>
382        fn as_vec_photo_size(&self) -> Option<Vec<PhotoSize>>
383        fn as_vec_sticker(&self) -> Option<Vec<Sticker>>
384        fn as_vec_keyboard_button(&self) -> Option<Vec<KeyboardButton>>
385        fn as_vec_inline_keyboard_button(&self) -> Option<Vec<InlineKeyboardButton>>
386        fn as_vec_message_entity(&self) -> Option<Vec<MessageEntity>>
387        fn as_vec_input_media(&self) -> Option<Vec<InputMedia>>
388        fn as_vec_message(&self) -> Option<Vec<Message>>
389        fn as_vec_chat_member(&self) -> Option<Vec<ChatMember>>
390        fn as_vec_bot_command(&self) -> Option<Vec<BotCommand>>
391    }
392    as_vec_vec_custom! {
393        fn as_vec_vec_photo_size(&self, as_vec_photo_size) -> Option<Vec<Vec<PhotoSize>>>
394        fn as_vec_vec_keyboard_button(&self, as_vec_keyboard_button) -> Option<Vec<Vec<KeyboardButton>>>
395        fn as_vec_vec_inline_keyboard_button(&self, as_vec_inline_keyboard_button) -> Option<Vec<Vec<InlineKeyboardButton>>>
396    }
397    as_box_custom! {
398        fn as_box_chat(&self) -> Option<Box<Chat>>
399        fn as_box_message(&self) -> Option<Box<Message>>
400    }
401    fn as_message_entity_type(&self) -> Option<MessageEntityType> {
402        if self.is_empty() {
403            None
404        } else {
405            Some(MessageEntityType::from_string(format!("{}", self)))
406        }
407    }
408}
409expand_from! {
410    impl From<Update> for JsonValue
411    impl From<User> for JsonValue
412    impl From<Location> for JsonValue
413    impl From<MessageEntity> for JsonValue
414    impl From<PhotoSize> for JsonValue
415    impl From<PollOption> for JsonValue
416    impl From<InlineKeyboardButton> for JsonValue
417    impl From<KeyboardButtonPollType> for JsonValue
418    impl From<KeyboardButton> for JsonValue
419    impl From<ForceReply> for JsonValue
420    impl From<ReplyKeyboardMarkup> for JsonValue
421    impl From<ReplyKeyboardRemove> for JsonValue
422    impl From<Audio> for JsonValue
423    impl From<Animation> for JsonValue
424    impl From<ChatPhoto> for JsonValue
425    impl From<ChatPermissions> for JsonValue
426    impl From<Venue> for JsonValue
427    impl From<Poll> for JsonValue
428    impl From<Dice> for JsonValue
429    impl From<Contact> for JsonValue
430    impl From<VoiceChatScheduled> for JsonValue
431    impl From<VoiceChatStarted> for JsonValue
432    impl From<VoiceChatEnded> for JsonValue
433    impl From<VoiceChatParticipantsInvited> for JsonValue
434    impl From<ProximityAlertTriggered> for JsonValue
435    impl From<MessageAutoDeleteTimerChanged> for JsonValue
436    impl From<InlineKeyboardMarkup> for JsonValue
437    impl From<Message> for JsonValue
438    impl From<Chat> for JsonValue
439    impl From<Video> for JsonValue
440    impl From<Voice> for JsonValue
441    impl From<VideoNote> for JsonValue
442    impl From<Document> for JsonValue
443    impl From<ChatMember> for JsonValue
444    impl From<ChatInviteLink> for JsonValue
445    impl From<LoginUrl> for JsonValue
446    impl From<ChatLocation> for JsonValue
447    impl From<CallbackQuery> for JsonValue
448    impl From<PollAnswer> for JsonValue
449    impl From<ChatMemberUpdated> for JsonValue
450    impl From<InputMedia> for JsonValue
451    impl From<Sticker> for JsonValue
452    impl From<MaskPosition> for JsonValue
453    impl From<UserProfilePhotos> for JsonValue
454    impl From<BotCommand> for JsonValue
455    impl From<StickerSet> for JsonValue
456}
457
458add_functionality! {
459pub struct Update {
460    pub update_id: i64,
461    pub message: Option<Message>,
462    pub edited_message: Option<Message>,
463    pub channel_post: Option<Message>,
464    pub edited_channel_post: Option<Message>,
465    pub callback_query: Option<CallbackQuery>,
466    pub poll: Option<Poll>,
467    pub poll_answer: Option<PollAnswer>,
468    pub my_chat_member: Option<ChatMemberUpdated>,
469    pub chat_member: Option<ChatMemberUpdated>
470}
471
472pub struct User {
473    pub id: i64,
474    pub is_bot: bool,
475    pub first_name: String,
476    pub last_name: Option<String>,
477    pub username: Option<String>,
478    pub language_code: Option<String>,
479    pub can_join_groups: Option<bool>,
480    pub can_read_all_group_messages: Option<bool>,
481    pub supports_inline_queries: Option<bool>
482}
483
484pub struct Chat {
485    pub id: i64,
486    pub typ: String,
487    pub title: Option<String>,
488    pub username: Option<String>,
489    pub first_name: Option<String>,
490    pub last_name: Option<String>,
491    pub photo: Option<ChatPhoto>,
492    pub bio: Option<String>,
493    pub description: Option<String>,
494    pub invite_link: Option<String>,
495    pub pinned_message: Option<Message>,
496    pub permissions: Option<ChatPermissions>,
497    pub slow_mode_delay: Option<i32>,
498    pub message_auto_delete_time: Option<i32>,
499    pub sticker_set_name: Option<String>,
500    pub can_set_sticker_set: Option<bool>,
501    pub linked_chat_id: Option<i64>,
502    pub location: Option<ChatLocation>
503}
504
505pub struct Message {
506    pub message_id: i32,
507    pub from: Option<User>,
508    pub sender_chat: Option<Box<Chat>>,
509    pub date: i32,
510    pub chat: Box<Chat>,
511    pub forward_from: Option<User>,
512    pub forward_from_chat: Option<Box<Chat>>,
513    pub forward_from_message_id: Option<i32>,
514    pub forward_signature: Option<String>,
515    pub forward_sender_name: Option<String>,
516    pub forward_date: Option<i32>,
517    pub reply_to_message: Option<Box<Message>>,
518    pub via_bot: Option<User>,
519    pub edit_date: Option<i32>,
520    pub media_group_id: Option<String>,
521    pub author_signature: Option<String>,
522    pub text: Option<String>,
523    pub entities: Option<Vec<MessageEntity>>,
524    pub animation: Option<Animation>,
525    pub audio: Option<Audio>,
526    pub document: Option<Document>,
527    pub photo: Option<Vec<PhotoSize>>,
528    pub sticker: Option<Sticker>,
529    pub video: Option<Video>,
530    pub video_note: Option<VideoNote>,
531    pub voice: Option<Voice>,
532    pub caption: Option<String>,
533    pub caption_entities: Option<Vec<MessageEntity>>,
534    pub contact: Option<Contact>,
535    pub dice: Option<Dice>,
536    pub poll: Option<Poll>,
537    pub venue: Option<Venue>,
538    pub location: Option<Location>,
539    pub new_chat_members: Option<Vec<User>>,
540    pub left_chat_member: Option<User>,
541    pub new_chat_title: Option<String>,
542    pub new_chat_photo: Option<Vec<PhotoSize>>,
543    pub delete_chat_photo: Option<bool>,
544    pub group_chat_created: Option<bool>,
545    pub supergroup_chat_created: Option<bool>,
546    pub channel_chat_created: Option<bool>,
547    pub message_auto_delete_timer_changed: Option<MessageAutoDeleteTimerChanged>,
548    pub migrate_to_chat_id: Option<i64>,
549    pub migrate_from_chat_id: Option<i64>,
550    pub pinned_message: Option<Box<Message>>,
551    pub connected_website: Option<String>,
552    pub proximity_alert_triggered: Option<ProximityAlertTriggered>,
553    pub voice_chat_scheduled: Option<VoiceChatScheduled>,
554    pub voice_chat_started: Option<VoiceChatStarted>,
555    pub voice_chat_ended: Option<VoiceChatEnded>,
556    pub voice_chat_participants_invited: Option<VoiceChatParticipantsInvited>,
557    pub reply_markup: Option<InlineKeyboardMarkup>
558}
559
560pub struct MessageId {
561    pub message_id: i32
562}
563
564pub struct MessageEntity {
565    pub typ: MessageEntityType,
566    pub offset: i32,
567    pub length: i32,
568    pub url: Option<String>,
569    pub user: Option<User>,
570    pub language: Option<String>
571}
572
573pub struct PhotoSize {
574    pub file_id: String,
575    pub file_unique_id: String,
576    pub width: i32,
577    pub height: i32,
578    pub file_size: Option<i32>
579}
580
581pub struct Animation {
582    pub file_id: String,
583    pub file_unique_id: String,
584    pub width: i32,
585    pub height: i32,
586    pub duration: i32,
587    pub thumb: Option<PhotoSize>,
588    pub file_name: Option<String>,
589    pub mime_type: Option<String>,
590    pub file_size: Option<i32>
591}
592
593pub struct Audio {
594    pub file_id: String,
595    pub file_unique_id: String,
596    pub duration: i32,
597    pub performer: Option<String>,
598    pub title: Option<String>,
599    pub file_name: Option<String>,
600    pub mime_type: Option<String>,
601    pub file_size: Option<i32>,
602    pub thumb: Option<PhotoSize>
603}
604
605pub struct Document {
606    pub file_id: String,
607    pub file_unique_id: String,
608    pub thumb: Option<PhotoSize>,
609    pub file_name: Option<String>,
610    pub mime_type: Option<String>,
611    pub file_size: Option<i32>
612}
613
614pub struct Video {
615    pub file_id: String,
616    pub file_unique_id: String,
617    pub width: i32,
618    pub height: i32,
619    pub duration: i32,
620    pub thumb: Option<PhotoSize>,
621    pub file_name: Option<String>,
622    pub mime_type: Option<String>,
623    pub file_size: Option<i32>
624}
625
626pub struct VideoNote {
627    pub file_id: String,
628    pub file_unique_id: String,
629    pub length: i32,
630    pub duration: i32,
631    pub thumb: Option<PhotoSize>,
632    pub file_size: Option<i32>
633}
634
635pub struct Voice {
636    pub file_id: String,
637    pub file_unique_id: String,
638    pub duration: i32,
639    pub mime_type: Option<String>,
640    pub file_size: Option<i32>
641}
642
643pub struct Contact {
644    pub phone_number: String,
645    pub first_name: String,
646    pub last_name: Option<String>,
647    pub user_id: Option<i64>,
648    pub vcard: Option<String>
649}
650
651pub struct Dice {
652    pub emoji: String,
653    pub value: i32
654}
655
656pub struct PollOption {
657    pub text: String,
658    pub voter_count: i32
659}
660
661pub struct PollAnswer {
662    pub poll_id: String,
663    pub user: User,
664    pub option_ids: Vec<i32>
665}
666
667pub struct Poll {
668    pub id: String,
669    pub question: String,
670    pub options: Vec<PollOption>,
671    pub total_voter_count: i32,
672    pub is_closed: bool,
673    pub is_anonymous: bool,
674    pub typ: String,
675    pub allows_multiple_answers: bool,
676    pub correct_option_id: Option<i32>,
677    pub explanation: Option<String>,
678    pub explanation_entities: Option<Vec<MessageEntity>>,
679    pub open_period: Option<i32>,
680    pub close_date: Option<i32>
681}
682
683pub struct Location {
684    pub longitude: f64,
685    pub latitude: f64,
686    pub horizontal_accuracy: Option<f64>,
687    pub live_period: Option<i32>,
688    pub heading: Option<i32>,
689    pub proximity_alert_radius: Option<i32>
690}
691
692pub struct Venue {
693    pub location: Location,
694    pub title: String,
695    pub address: String,
696    pub foursquare_id: Option<String>,
697    pub foursquare_type: Option<String>,
698    pub google_place_id: Option<String>,
699    pub google_place_type: Option<String>
700}
701
702pub struct ProximityAlertTriggered {
703    pub traveler: User,
704    pub watcher: User,
705    pub distance: i32
706}
707
708pub struct MessageAutoDeleteTimerChanged {
709    pub message_auto_delete_time: i32
710}
711
712pub struct VoiceChatScheduled {
713    pub start_date: i32
714}
715
716pub struct VoiceChatEnded {
717    pub duration: i32
718}
719
720pub struct VoiceChatParticipantsInvited {
721    pub users: Vec<User>
722}
723
724pub struct UserProfilePhotos {
725    pub total_count: i32,
726    pub photos: Vec<Vec<PhotoSize>>
727}
728
729pub struct File {
730    pub file_id: String,
731    pub file_unique_id: String,
732    pub file_size: Option<String>,
733    pub file_path: Option<String>
734}
735
736pub struct ReplyKeyboardMarkup {
737    pub keyboard: Vec<Vec<KeyboardButton>>,
738    pub resize_keyboard: Option<bool>,
739    pub one_time_keyboard: Option<bool>,
740    pub selective: Option<bool>
741}
742
743pub struct KeyboardButton {
744    pub text: String,
745    pub request_contact: Option<bool>,
746    pub request_location: Option<bool>,
747    pub request_poll: Option<KeyboardButtonPollType>
748}
749
750pub struct KeyboardButtonPollType {
751    pub typ: String
752}
753
754pub struct ReplyKeyboardRemove {
755    pub remove_keyboard: bool, // should always be true
756    pub selective: Option<bool>
757}
758
759pub struct InlineKeyboardMarkup {
760    pub inline_keyboard: Vec<Vec<InlineKeyboardButton>>
761}
762
763pub struct InlineKeyboardButton {
764    pub text: String,
765    pub url: Option<String>,
766    pub login_url: Option<LoginUrl>,
767    pub callback_data: Option<String>,
768    pub switch_inline_query: Option<String>,
769    pub switch_inline_query_current_chat: Option<String>,
770    pub pay: Option<bool>
771}
772
773pub struct LoginUrl {
774    pub url: String,
775    pub forward_text: Option<String>,
776    pub bot_username: Option<String>,
777    pub request_write_access: Option<bool>
778}
779
780pub struct CallbackQuery {
781    pub id: String,
782    pub from: User,
783    pub message: Option<Message>,
784    pub inline_message_id: Option<String>,
785    pub chat_instance: Option<String>,
786    pub data: Option<String>,
787    pub game_short_name: Option<String>
788}
789
790pub struct ForceReply {
791    pub force_reply: bool, //should always be true
792    pub selective: Option<bool>
793}
794
795pub struct ChatPhoto {
796    pub small_file_id: String,
797    pub small_file_unique_id: String,
798    pub big_file_id: String,
799    pub big_file_unique_id: String
800}
801
802pub struct ChatInviteLink {
803    pub invite_link: String,
804    pub creator: User,
805    pub is_primary: bool,
806    pub is_revoked: bool,
807    pub expire_date: Option<i32>,
808    pub member_limit: Option<i32>
809}
810
811pub struct ChatMember {
812    pub user: User,
813    pub status: String,
814    pub custom_title: Option<String>,
815    pub is_anonymous: Option<bool>,
816    pub can_be_edited: Option<bool>,
817    pub can_manage_chat: Option<bool>,
818    pub can_post_messages: Option<bool>,
819    pub can_edit_messages: Option<bool>,
820    pub can_delete_messages: Option<bool>,
821    pub can_manage_voice_chats: Option<bool>,
822    pub can_restrict_members: Option<bool>,
823    pub can_promote_members: Option<bool>,
824    pub can_change_info: Option<bool>,
825    pub can_invite_users: Option<bool>,
826    pub can_pin_messages: Option<bool>,
827    pub is_member: Option<bool>,
828    pub can_send_messages: Option<bool>,
829    pub can_send_media_messages: Option<bool>,
830    pub can_send_polls: Option<bool>,
831    pub can_send_other_messages: Option<bool>,
832    pub can_add_web_page_previews: Option<bool>,
833    pub until_date: Option<i32>
834}
835
836pub struct ChatMemberUpdated {
837    pub chat: Chat,
838    pub from: User,
839    pub date: i32,
840    pub old_chat_member: ChatMember,
841    pub new_chat_member: ChatMember,
842    pub invite_link: Option<ChatInviteLink>
843}
844
845pub struct ChatPermissions {
846    pub can_send_messages: Option<bool>,
847    pub can_send_media_messages: Option<bool>,
848    pub can_send_polls: Option<bool>,
849    pub can_send_other_messages: Option<bool>,
850    pub can_add_web_page_previews: Option<bool>,
851    pub can_change_info: Option<bool>,
852    pub can_invite_users: Option<bool>,
853    pub can_pin_messages: Option<bool>
854}
855
856pub struct ChatLocation {
857    pub location: Location,
858    pub address: String
859}
860
861pub struct BotCommand {
862    pub command: String,
863    pub description: String
864}
865
866pub struct ResponseParameters {
867    pub migrate_to_chat_id: Option<i32>,
868    pub retry_after: Option<i32>
869}
870
871pub struct InputMedia {
872    pub typ: String,
873    pub media: String,
874    pub caption: Option<String>,
875    pub parse_mode: Option<String>,
876    pub caption_entities: Option<Vec<MessageEntity>>,
877    pub width: Option<i32>,
878    pub height: Option<i32>,
879    pub duration: Option<i32>,
880    pub supports_streaming: Option<bool>,
881    pub performer: Option<String>,
882    pub title: Option<String>,
883    pub disable_content_type_detection: Option<bool>
884}
885
886pub struct Sticker {
887    pub file_id: String,
888    pub file_unique_id: String,
889    pub width: i32,
890    pub height: i32,
891    pub is_animated: bool,
892    pub thumb: Option<PhotoSize>,
893    pub emoji: Option<String>,
894    pub set_name: Option<String>,
895    pub mask_position: Option<MaskPosition>,
896    pub file_size: Option<i32>
897}
898
899pub struct StickerSet {
900    pub name: String,
901    pub title: String,
902    pub is_animated: bool,
903    pub contains_masks: bool,
904    pub stickers: Vec<Sticker>,
905    pub thumb: Option<PhotoSize>
906}
907
908pub struct MaskPosition {
909    pub point: String,
910    pub x_shift: f64,
911    pub y_shift: f64,
912    pub scale: f64
913}}
914
915add_functionality_empty! {
916    pub struct VoiceChatStarted {
917}}
918
919#[cfg(test)]
920mod tests {
921    use super::*;
922
923    #[test]
924    fn test_empty_user() {
925        let actual = format!("{}", User::empty().to_json());
926        let reference = "{\"id\":0,\"is_bot\":false,\"first_name\":\"\"}".to_string();
927        assert_eq!(actual, reference);
928    }
929
930    #[test]
931    fn test_minimal_user() {
932        let json_user = json::parse("{\"id\":1234,\"is_bot\":true,\"first_name\":\"iamgroot\"}");
933        let user;
934        match json_user {
935            Ok(json_data) => user = User::from_json(json_data),
936            Err(_) => user = User::empty(),
937        }
938        let actual = format!("{}", user.to_json());
939        let reference = "{\"id\":1234,\"is_bot\":true,\"first_name\":\"iamgroot\"}".to_string();
940        assert_eq!(actual, reference);
941    }
942
943    #[test]
944    fn test_full_user() {
945        let reference = "{\"id\":1234,\"is_bot\":true,\"first_name\":\"iAm\",\
946            \"last_name\":\"groot\",\"language_code\":\"US\",\"can_join_groups\":true,\
947            \"can_read_all_group_messages\":false,\"supports_inline_queries\":true}"
948            .to_string();
949        let json_user = json::parse(reference.as_str());
950        let user;
951        match json_user {
952            Ok(json_data) => user = User::from_json(json_data),
953            Err(_) => user = User::empty(),
954        }
955        let actual = format!("{}", user.to_json());
956        assert_eq!(actual, reference);
957    }
958
959    #[test]
960    #[should_panic(expected = "called `Option::unwrap()` on a `None` value")]
961    fn test_invalid_user() {
962        let json_user = json::parse("{\"id\":1234,\"first_name\":\"iamgroot\"}");
963        let _user;
964        match json_user {
965            Ok(json_data) => _user = User::from_json(json_data),
966            Err(_) => _user = User::empty(),
967        }
968    }
969
970    #[test]
971    fn test_clone_user() {
972        let mut user = User::empty();
973        let orig_user = user.clone();
974        user.first_name = "ichangedmyname".to_string();
975        let actual1 = format!("{}", user.to_json());
976        let reference1 =
977            "{\"id\":0,\"is_bot\":false,\"first_name\":\"ichangedmyname\"}".to_string();
978        assert_eq!(actual1, reference1);
979        let actual2 = format!("{}", orig_user.to_json());
980        let reference2 = "{\"id\":0,\"is_bot\":false,\"first_name\":\"\"}".to_string();
981        assert_eq!(actual2, reference2);
982    }
983
984    #[test]
985    fn test_display_user() {
986        let user = User::empty();
987        let reference = "id: 0; is_bot: false; first_name: ".to_string();
988        let actual = format!("{}", user);
989        assert_eq!(actual, reference);
990    }
991
992    #[test]
993    fn test_large_user_id() {
994        let mut user = User::empty();
995        user.id = 288230376151711744;
996        let reference = "id: 288230376151711744; is_bot: false; first_name: ".to_string();
997        let actual = format!("{}", user);
998        assert_eq!(actual, reference);
999    }
1000
1001    #[test]
1002    fn test_empty_me() {
1003        let actual = format!("{}", MessageEntity::empty().to_json());
1004        let reference = "{\"type\":\"mention\",\"offset\":0,\"length\":0}".to_string();
1005        assert_eq!(actual, reference);
1006    }
1007
1008    #[test]
1009    fn test_minimal_me() {
1010        let json_me = json::parse("{\"type\":\"cashtag\",\"offset\":42,\"length\":69}");
1011        let me;
1012        match json_me {
1013            Ok(json_data) => me = MessageEntity::from_json(json_data),
1014            Err(_) => me = MessageEntity::empty(),
1015        }
1016        let actual = format!("{}", me.to_json());
1017        let reference = "{\"type\":\"cashtag\",\"offset\":42,\"length\":69}".to_string();
1018        assert_eq!(actual, reference);
1019    }
1020
1021    #[test]
1022    fn test_full_me() {
1023        let reference = "{\"type\":\"cashtag\",\"offset\":42,\"length\":69,\
1024            \"url\":\"https://example.org\",\"user\":{\"id\":0,\"is_bot\":false,\"first_name\":\"user\"},\
1025            \"language\":\"python\"}".to_string();
1026        let json_me = json::parse(reference.as_str());
1027        let me;
1028        match json_me {
1029            Ok(json_data) => me = MessageEntity::from_json(json_data),
1030            Err(_) => me = MessageEntity::empty(),
1031        }
1032        let actual = format!("{}", me.to_json());
1033        assert_eq!(actual, reference);
1034    }
1035
1036    #[test]
1037    #[should_panic(expected = "called `Option::unwrap()` on a `None` value")]
1038    fn test_invalid_me() {
1039        let json_me = json::parse("{\"type\":\"cashtag\",\"length\":69}");
1040        let _me;
1041        match json_me {
1042            Ok(json_data) => _me = MessageEntity::from_json(json_data),
1043            Err(_) => _me = MessageEntity::empty(),
1044        }
1045    }
1046
1047    #[test]
1048    fn test_clone_me() {
1049        let mut me = MessageEntity::empty();
1050        let orig_me = me.clone();
1051        me.offset = 42;
1052        let actual1 = format!("{}", me.to_json());
1053        let reference1 = "{\"type\":\"mention\",\"offset\":42,\"length\":0}".to_string();
1054        assert_eq!(actual1, reference1);
1055        let actual2 = format!("{}", orig_me.to_json());
1056        let reference2 = "{\"type\":\"mention\",\"offset\":0,\"length\":0}".to_string();
1057        assert_eq!(actual2, reference2);
1058    }
1059
1060    #[test]
1061    fn test_display_me() {
1062        let me = MessageEntity::empty();
1063        let reference = "type: mention; offset: 0; length: 0".to_string();
1064        let actual = format!("{}", me);
1065        assert_eq!(actual, reference);
1066    }
1067
1068    #[test]
1069    fn test_input_media_photo() {
1070        let reference = r#"{"type":"photo","media":"test1234","caption_entities":[{"type":"mention","offset":0,"length":0},{"type":"mention","offset":1,"length":0}]}"#;
1071        expand_basic_test! {
1072            fn run_test(InputMedia, reference)
1073        }
1074    }
1075
1076    #[test]
1077    fn test_chat_photo() {
1078        let reference = r#"{"small_file_id":"1","small_file_unique_id":"1234","big_file_id":"2","big_file_unique_id":"2345"}"#;
1079        expand_basic_test! {
1080            fn run_test(ChatPhoto, reference)
1081        }
1082    }
1083
1084    #[test]
1085    fn test_chat_invite_link() {
1086        let reference = r#"{"invite_link":"hello","creator":{"id":1234,"is_bot":true,"first_name":"groot"},"is_primary":true,"is_revoked":false}"#;
1087        expand_basic_test! {
1088            fn run_test(ChatInviteLink, reference)
1089        }
1090    }
1091
1092    #[test]
1093    fn test_chat_member() {
1094        let reference =
1095            r#"{"user":{"id":1234,"is_bot":true,"first_name":"groot"},"status":"creator"}"#;
1096        expand_basic_test! {
1097            fn run_test(ChatMember, reference)
1098        }
1099    }
1100
1101    #[test]
1102    fn test_chat_permissions() {
1103        let reference = r#"{"can_send_messages":true}"#;
1104        expand_basic_test! {
1105            fn run_test(ChatPermissions, reference)
1106        }
1107    }
1108
1109    #[test]
1110    fn test_bot_command() {
1111        let reference = r#"{"command":"do_it","description":"Lets do it"}"#;
1112        expand_basic_test! {
1113            fn run_test(BotCommand, reference)
1114        }
1115    }
1116
1117    #[test]
1118    fn test_response_parameters() {
1119        let reference = r#"{"migrate_to_chat_id":1,"retry_after":120}"#;
1120        expand_basic_test! {
1121            fn run_test(ResponseParameters, reference)
1122        }
1123    }
1124
1125    #[test]
1126    fn test_photo_size() {
1127        let reference =
1128            r#"{"file_id":"1","file_unique_id":"1234","width":800,"height":600,"file_size":1024}"#;
1129        expand_basic_test! {
1130            fn run_test(PhotoSize, reference)
1131        }
1132    }
1133
1134    #[test]
1135    fn test_animation() {
1136        let reference = r#"{"file_id":"1","file_unique_id":"12345","width":600,"height":800,"duration":10,"thumb":{"file_id":"1","file_unique_id":"1234","width":800,"height":600}}"#;
1137        expand_basic_test! {
1138            fn run_test(Animation, reference)
1139        }
1140    }
1141
1142    #[test]
1143    fn test_audio() {
1144        let reference = r#"{"file_id":"1","file_unique_id":"12345","duration":60}"#;
1145        expand_basic_test! {
1146            fn run_test(Audio, reference)
1147        }
1148    }
1149
1150    #[test]
1151    fn test_document() {
1152        let reference = r#"{"file_id":"1","file_unique_id":"12345"}"#;
1153        expand_basic_test! {
1154            fn run_test(Document, reference)
1155        }
1156    }
1157
1158    #[test]
1159    fn test_video() {
1160        let reference =
1161            r#"{"file_id":"1","file_unique_id":"12345","width":800,"height":600,"duration":24}"#;
1162        expand_basic_test! {
1163            fn run_test(Video, reference)
1164        }
1165    }
1166
1167    #[test]
1168    fn test_video_note() {
1169        let reference = r#"{"file_id":"1","file_unique_id":"12345","length":120,"duration":10}"#;
1170        expand_basic_test! {
1171            fn run_test(VideoNote, reference)
1172        }
1173    }
1174
1175    #[test]
1176    fn test_voice() {
1177        let reference = r#"{"file_id":"1","file_unique_id":"12345","duration":5}"#;
1178        expand_basic_test! {
1179            fn run_test(Voice, reference)
1180        }
1181    }
1182
1183    #[test]
1184    fn test_contact() {
1185        let reference = r#"{"phone_number":"01234","first_name":"me","user_id":1234567890}"#;
1186        expand_basic_test! {
1187            fn run_test(Contact, reference)
1188        }
1189    }
1190
1191    #[test]
1192    fn test_dice() {
1193        let reference = r#"{"emoji":"dice","value":4}"#;
1194        expand_basic_test! {
1195            fn run_test(Dice, reference)
1196        }
1197    }
1198
1199    #[test]
1200    fn test_poll_option() {
1201        let reference = r#"{"text":"nein","voter_count":3}"#;
1202        expand_basic_test! {
1203            fn run_test(PollOption, reference)
1204        }
1205    }
1206
1207    #[test]
1208    fn test_poll_answer() {
1209        let reference = r#"{"poll_id":"01234","user":{"id":123654,"is_bot":true,"first_name":"me"},"option_ids":[1,2,3,4,5]}"#;
1210        expand_basic_test! {
1211            fn run_test(PollAnswer, reference)
1212        }
1213    }
1214
1215    #[test]
1216    fn test_poll() {
1217        let reference = r#"{"id":"1234","question":"right?","options":[{"text":"nein","voter_count":3},{"text":"ja","voter_count":4}],"total_voter_count":7,"is_closed":true,"is_anonymous":false,"type":"regular","allows_multiple_answers":false,"explanation_entities":[{"type":"mention","offset":10,"length":20},{"type":"cashtag","offset":1,"length":2}]}"#;
1218        expand_basic_test! {
1219            fn run_test(Poll, reference)
1220        }
1221    }
1222
1223    #[test]
1224    fn test_location() {
1225        let reference = r#"{"longitude":49.5,"latitude":9.4,"horizontal_accuracy":0.2}"#;
1226        expand_basic_test! {
1227            fn run_test(Location, reference)
1228        }
1229    }
1230
1231    #[test]
1232    fn test_venue() {
1233        let reference =
1234            r#"{"location":{"longitude":49.5,"latitude":9.4},"title":"home","address":"at home"}"#;
1235        expand_basic_test! {
1236            fn run_test(Venue, reference)
1237        }
1238    }
1239
1240    #[test]
1241    fn test_proximity_alert_triggered() {
1242        let reference = r#"{"traveler":{"id":123654,"is_bot":true,"first_name":"travel"},"watcher":{"id":123654,"is_bot":true,"first_name":"watch"},"distance":100}"#;
1243        expand_basic_test! {
1244            fn run_test(ProximityAlertTriggered, reference)
1245        }
1246    }
1247
1248    #[test]
1249    fn test_message_id() {
1250        let reference = r#"{"message_id":12334}"#;
1251        expand_basic_test! {
1252            fn run_test(MessageId, reference)
1253        }
1254    }
1255
1256    #[test]
1257    fn test_message_auto_delete_timer_changed() {
1258        let reference = r#"{"message_auto_delete_time":100}"#;
1259        expand_basic_test! {
1260            fn run_test(MessageAutoDeleteTimerChanged, reference)
1261        }
1262    }
1263
1264    #[test]
1265    fn test_voice_chat_scheduled() {
1266        let reference = r#"{"start_date":100}"#;
1267        expand_basic_test! {
1268            fn run_test(VoiceChatScheduled, reference)
1269        }
1270    }
1271
1272    #[test]
1273    fn test_voice_started() {
1274        let reference = r#"{}"#;
1275        expand_basic_test! {
1276            fn run_test(VoiceChatStarted, reference)
1277        }
1278    }
1279
1280    #[test]
1281    fn test_voice_chat_ended() {
1282        let reference = r#"{"duration":100}"#;
1283        expand_basic_test! {
1284            fn run_test(VoiceChatEnded, reference)
1285        }
1286    }
1287
1288    #[test]
1289    fn test_voice_chat_participants_invited() {
1290        let reference = r#"{"users":[{"id":123654,"is_bot":true,"first_name":"user1"},{"id":12365,"is_bot":true,"first_name":"user2"}]}"#;
1291        expand_basic_test! {
1292            fn run_test(VoiceChatParticipantsInvited, reference)
1293        }
1294    }
1295
1296    #[test]
1297    fn test_user_profile_photos() {
1298        let reference = r#"{"total_count":2,"photos":[[{"file_id":"1","file_unique_id":"1234","width":800,"height":600},{"file_id":"2","file_unique_id":"1234","width":600,"height":800}],[{"file_id":"3","file_unique_id":"1234","width":800,"height":600},{"file_id":"4","file_unique_id":"1234","width":600,"height":800}]]}"#;
1299        expand_basic_test! {
1300            fn run_test(UserProfilePhotos, reference)
1301        }
1302    }
1303
1304    #[test]
1305    fn test_file() {
1306        let reference = r#"{"file_id":"1","file_unique_id":"1234"}"#;
1307        expand_basic_test! {
1308            fn run_test(File, reference)
1309        }
1310    }
1311
1312    #[test]
1313    fn test_reply_keyboard_markup() {
1314        let reference = r#"{"keyboard":[[{"text":"quiz1"},{"text":"quiz2"}],[{"text":"quiz3"},{"text":"quiz4"}]]}"#;
1315        expand_basic_test! {
1316            fn run_test(ReplyKeyboardMarkup, reference)
1317        }
1318    }
1319
1320    #[test]
1321    fn test_keyboard_button() {
1322        let reference = r#"{"text":"quiz","request_poll":{"type":"quiz"}}"#;
1323        expand_basic_test! {
1324            fn run_test(KeyboardButton, reference)
1325        }
1326    }
1327
1328    #[test]
1329    fn test_keyboard_button_poll_type() {
1330        let reference = r#"{"type":"quiz"}"#;
1331        expand_basic_test! {
1332            fn run_test(KeyboardButtonPollType, reference)
1333        }
1334    }
1335
1336    #[test]
1337    fn test_reply_keyboard_remove() {
1338        let reference = r#"{"remove_keyboard":true}"#;
1339        expand_basic_test! {
1340            fn run_test(ReplyKeyboardRemove, reference)
1341        }
1342    }
1343
1344    #[test]
1345    fn test_login_url() {
1346        let reference = r#"{"url":"https://its.me"}"#;
1347        expand_basic_test! {
1348            fn run_test(LoginUrl, reference)
1349        }
1350    }
1351
1352    #[test]
1353    fn test_force_reply() {
1354        let reference = r#"{"force_reply":true}"#;
1355        expand_basic_test! {
1356            fn run_test(ForceReply, reference)
1357        }
1358    }
1359
1360    #[test]
1361    fn test_chat_location() {
1362        let reference = r#"{"location":{"longitude":49.5,"latitude":9.4},"address":"home"}"#;
1363        expand_basic_test! {
1364            fn run_test(ChatLocation, reference)
1365        }
1366    }
1367
1368    #[test]
1369    fn test_input_media() {
1370        let reference = r#"{"type":"video","media":"dummy"}"#;
1371        expand_basic_test! {
1372            fn run_test(InputMedia, reference)
1373        }
1374    }
1375
1376    #[test]
1377    fn test_sticker() {
1378        let reference = r#"{"file_id":"1","file_unique_id":"1234","width":64,"height":64,"is_animated":true,"thumb":{"file_id":"1","file_unique_id":"1234","width":800,"height":600},"mask_position":{"point":"chin","x_shift":1.1,"y_shift":2.5,"scale":2.1}}"#;
1379        expand_basic_test! {
1380            fn run_test(Sticker, reference)
1381        }
1382    }
1383
1384    #[test]
1385    fn test_sticker_set() {
1386        let reference = r#"{"name":"stickerset","title":"stickers","is_animated":true,"contains_masks":false,"stickers":[{"file_id":"1","file_unique_id":"1234","width":64,"height":64,"is_animated":true},{"file_id":"2","file_unique_id":"2345","width":32,"height":32,"is_animated":false}]}"#;
1387        expand_basic_test! {
1388            fn run_test(StickerSet, reference)
1389        }
1390    }
1391
1392    #[test]
1393    fn test_mask_position() {
1394        let reference = r#"{"point":"chin","x_shift":1.3,"y_shift":2.5,"scale":2.1}"#;
1395        expand_basic_test! {
1396            fn run_test(MaskPosition, reference)
1397        }
1398    }
1399
1400    #[test]
1401    fn test_chat_member_updated() {
1402        let reference = r#"{"chat":{"id":1234,"type":"private"},"from":{"id":1234,"is_bot":true,"first_name":"itsme"},"date":12,"old_chat_member":{"user":{"id":1234,"is_bot":true,"first_name":"groot"},"status":"creator"},"new_chat_member":{"user":{"id":1234,"is_bot":true,"first_name":"root"},"status":"creator"}}"#;
1403        expand_basic_test! {
1404            fn run_test(ChatMemberUpdated, reference)
1405        }
1406    }
1407
1408    #[test]
1409    fn test_callback_query() {
1410        let reference = r#"{"id":"1234","from":{"id":1234,"is_bot":true,"first_name":"itsme"},"message":{"message_id":10,"date":5,"chat":{"id":12,"type":"private"}}}"#;
1411        expand_basic_test! {
1412            fn run_test(CallbackQuery, reference)
1413        }
1414    }
1415
1416    #[test]
1417    fn test_inline_keyboard_button() {
1418        let reference = r#"{"text":"hello","login_url":{"url":"https://example.com"}}"#;
1419        expand_basic_test! {
1420            fn run_test(InlineKeyboardButton, reference)
1421        }
1422    }
1423
1424    #[test]
1425    fn test_inline_keyboard_markup() {
1426        let reference = r#"{"inline_keyboard":[[{"text":"hello1"},{"text":"hello2"}],[{"text":"hello3"},{"text":"hello4"}]]}"#;
1427        expand_basic_test! {
1428            fn run_test(InlineKeyboardMarkup, reference)
1429        }
1430    }
1431
1432    #[test]
1433    fn test_chat() {
1434        let reference = r#"{"id":1,"type":"private","photo":{"small_file_id":"1","small_file_unique_id":"1234","big_file_id":"2","big_file_unique_id":"2345"},"pinned_message":{"message_id":10,"date":5,"chat":{"id":12,"type":"private"}},"permissions":{"can_send_messages":true},"location":{"location":{"longitude":49.1,"latitude":10.2},"address":"here"}}"#;
1435        expand_basic_test! {
1436            fn run_test(Chat, reference)
1437        }
1438    }
1439
1440    #[test]
1441    fn test_message() {
1442        let reference = r#"{"message_id":32,"from":{"id":1234,"is_bot":true,"first_name":"itsme"},"sender_chat":{"id":12345,"type":"group"},"date":5,"chat":{"id":12,"type":"private"},"reply_to_message":{"message_id":10,"date":5,"chat":{"id":12,"type":"private"}}}"#;
1443        expand_basic_test! {
1444            fn run_test(Message, reference)
1445        }
1446    }
1447
1448    #[test]
1449    fn test_update() {
1450        let reference = r#"{"update_id":10,"message":{"message_id":10,"date":5,"chat":{"id":12,"type":"private"}},"poll_answer":{"poll_id":"test","user":{"id":13,"is_bot":false,"first_name":"user"},"option_ids":[0,1,2]}}"#;
1451        expand_basic_test! {
1452            fn run_test(Update, reference)
1453        }
1454    }
1455}