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