1use std::{error::Error, fmt};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 api::{Method, Payload},
7 types::{ChatAdministratorRights, ChatId, Integer},
8};
9
10#[cfg(test)]
11mod tests;
12
13#[serde_with::skip_serializing_none]
15#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
16pub struct Bot {
17 pub first_name: String,
19 pub id: Integer,
21 pub username: String,
23 pub can_connect_to_business: bool,
25 pub can_join_groups: bool,
27 pub can_read_all_group_messages: bool,
29 pub has_main_web_app: bool,
31 pub last_name: Option<String>,
33 pub supports_inline_queries: bool,
35}
36
37impl Bot {
38 pub fn new<A, B>(id: Integer, username: A, first_name: B) -> Self
46 where
47 A: Into<String>,
48 B: Into<String>,
49 {
50 Self {
51 first_name: first_name.into(),
52 id,
53 username: username.into(),
54 can_connect_to_business: false,
55 can_join_groups: false,
56 can_read_all_group_messages: false,
57 has_main_web_app: false,
58 last_name: None,
59 supports_inline_queries: false,
60 }
61 }
62
63 pub fn with_can_connect_to_business(mut self, value: bool) -> Self {
69 self.can_connect_to_business = value;
70 self
71 }
72
73 pub fn with_can_join_groups(mut self, value: bool) -> Self {
79 self.can_join_groups = value;
80 self
81 }
82
83 pub fn with_can_read_all_group_messages(mut self, value: bool) -> Self {
89 self.can_read_all_group_messages = value;
90 self
91 }
92
93 pub fn with_has_main_web_app(mut self, value: bool) -> Self {
99 self.has_main_web_app = value;
100 self
101 }
102
103 pub fn with_last_name<T>(mut self, value: T) -> Self
109 where
110 T: Into<String>,
111 {
112 self.last_name = Some(value.into());
113 self
114 }
115
116 pub fn with_supports_inline_queries(mut self, value: bool) -> Self {
122 self.supports_inline_queries = value;
123 self
124 }
125}
126
127#[derive(Clone, Debug, Deserialize, Serialize)]
129pub struct BotCommand {
130 #[serde(rename = "command")]
131 name: String,
132 description: String,
133}
134
135impl BotCommand {
136 const MIN_NAME_LEN: usize = 1;
137 const MAX_NAME_LEN: usize = 32;
138 const MIN_DESCRIPTION_LEN: usize = 3;
139 const MAX_DESCRIPTION_LEN: usize = 256;
140
141 pub fn new<C, D>(name: C, description: D) -> Result<Self, BotCommandError>
149 where
150 C: Into<String>,
151 D: Into<String>,
152 {
153 let name = name.into();
154 let description = description.into();
155 let name_len = name.len();
156 let description_len = description.len();
157 if !(Self::MIN_NAME_LEN..=Self::MAX_NAME_LEN).contains(&name_len) {
158 Err(BotCommandError::BadNameLen(name_len))
159 } else if !(Self::MIN_DESCRIPTION_LEN..=Self::MAX_DESCRIPTION_LEN).contains(&description_len) {
160 Err(BotCommandError::BadDescriptionLen(description_len))
161 } else {
162 Ok(Self { name, description })
163 }
164 }
165
166 pub fn name(&self) -> &str {
168 &self.name
169 }
170
171 pub fn with_name<T>(mut self, value: T) -> Self
177 where
178 T: Into<String>,
179 {
180 self.name = value.into();
181 self
182 }
183
184 pub fn description(&self) -> &str {
186 &self.description
187 }
188
189 pub fn with_description<T>(mut self, value: T) -> Self
195 where
196 T: Into<String>,
197 {
198 self.description = value.into();
199 self
200 }
201}
202
203#[derive(Debug)]
205pub enum BotCommandError {
206 BadNameLen(usize),
208 BadDescriptionLen(usize),
210}
211
212impl Error for BotCommandError {}
213
214impl fmt::Display for BotCommandError {
215 fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
216 use self::BotCommandError::*;
217 match self {
218 BadNameLen(len) => write!(
219 out,
220 "command name can have a length of {} up to {} characters, got {}",
221 BotCommand::MIN_NAME_LEN,
222 BotCommand::MAX_NAME_LEN,
223 len
224 ),
225 BadDescriptionLen(len) => write!(
226 out,
227 "command description can have a length of {} up to {} characters, got {}",
228 BotCommand::MIN_DESCRIPTION_LEN,
229 BotCommand::MAX_DESCRIPTION_LEN,
230 len
231 ),
232 }
233 }
234}
235
236#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
238#[serde(tag = "type")]
239#[serde(rename_all = "snake_case")]
240pub enum BotCommandScope {
241 AllChatAdministrators,
243 AllGroupChats,
245 AllPrivateChats,
247 Chat {
249 chat_id: ChatId,
251 },
252 ChatAdministrators {
254 chat_id: ChatId,
256 },
257 ChatMember {
259 chat_id: ChatId,
261 user_id: Integer,
263 },
264 Default,
268}
269
270impl BotCommandScope {
271 pub fn chat<T>(value: T) -> Self
277 where
278 T: Into<ChatId>,
279 {
280 Self::Chat { chat_id: value.into() }
281 }
282
283 pub fn chat_administrators<T>(value: T) -> Self
290 where
291 T: Into<ChatId>,
292 {
293 Self::ChatAdministrators { chat_id: value.into() }
294 }
295
296 pub fn chat_member<A>(chat_id: A, user_id: Integer) -> Self
303 where
304 A: Into<ChatId>,
305 {
306 Self::ChatMember {
307 chat_id: chat_id.into(),
308 user_id,
309 }
310 }
311}
312
313#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
315pub struct BotDescription {
316 pub description: String,
318}
319
320impl BotDescription {
321 pub fn new<T>(value: T) -> Self
327 where
328 T: Into<String>,
329 {
330 Self {
331 description: value.into(),
332 }
333 }
334}
335
336#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
338pub struct BotName {
339 pub name: String,
341}
342
343impl BotName {
344 pub fn new<T>(value: T) -> Self
350 where
351 T: Into<String>,
352 {
353 Self { name: value.into() }
354 }
355}
356
357#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
359pub struct BotShortDescription {
360 pub short_description: String,
362}
363
364impl BotShortDescription {
365 pub fn new<T>(value: T) -> Self
371 where
372 T: Into<String>,
373 {
374 Self {
375 short_description: value.into(),
376 }
377 }
378}
379
380#[derive(Clone, Copy, Debug)]
387pub struct Close;
388
389impl Method for Close {
390 type Response = bool;
391
392 fn into_payload(self) -> Payload {
393 Payload::empty("close")
394 }
395}
396
397#[serde_with::skip_serializing_none]
401#[derive(Clone, Debug, Default, Serialize)]
402pub struct DeleteBotCommands {
403 language_code: Option<String>,
404 scope: Option<BotCommandScope>,
405}
406
407impl DeleteBotCommands {
408 pub fn with_language_code<T>(mut self, value: T) -> Self
414 where
415 T: Into<String>,
416 {
417 self.language_code = Some(value.into());
418 self
419 }
420
421 pub fn with_scope(mut self, value: BotCommandScope) -> Self {
427 self.scope = Some(value);
428 self
429 }
430}
431
432impl Method for DeleteBotCommands {
433 type Response = bool;
434
435 fn into_payload(self) -> Payload {
436 Payload::json("deleteMyCommands", self)
437 }
438}
439
440#[derive(Clone, Copy, Debug)]
442pub struct GetBot;
443
444impl Method for GetBot {
445 type Response = Bot;
446
447 fn into_payload(self) -> Payload {
448 Payload::empty("getMe")
449 }
450}
451
452#[serde_with::skip_serializing_none]
454#[derive(Clone, Debug, Default, Serialize)]
455pub struct GetBotCommands {
456 language_code: Option<String>,
457 scope: Option<BotCommandScope>,
458}
459
460impl GetBotCommands {
461 pub fn with_language_code<T>(mut self, value: T) -> Self
467 where
468 T: Into<String>,
469 {
470 self.language_code = Some(value.into());
471 self
472 }
473
474 pub fn with_scope(mut self, value: BotCommandScope) -> Self {
480 self.scope = Some(value);
481 self
482 }
483}
484
485impl Method for GetBotCommands {
486 type Response = Vec<BotCommand>;
487
488 fn into_payload(self) -> Payload {
489 Payload::json("getMyCommands", self)
490 }
491}
492
493#[serde_with::skip_serializing_none]
495#[derive(Clone, Copy, Debug, Default, Serialize)]
496pub struct GetBotDefaultAdministratorRights {
497 for_channels: Option<bool>,
498}
499
500impl GetBotDefaultAdministratorRights {
501 pub fn with_for_channels(mut self, value: bool) -> Self {
507 self.for_channels = Some(value);
508 self
509 }
510}
511
512impl Method for GetBotDefaultAdministratorRights {
513 type Response = ChatAdministratorRights;
514
515 fn into_payload(self) -> Payload {
516 Payload::json("getMyDefaultAdministratorRights", self)
517 }
518}
519
520#[serde_with::skip_serializing_none]
522#[derive(Clone, Debug, Default, Serialize)]
523pub struct GetBotDescription {
524 language_code: Option<String>,
525}
526
527impl GetBotDescription {
528 pub fn with_language_code<T>(mut self, value: T) -> Self
534 where
535 T: Into<String>,
536 {
537 self.language_code = Some(value.into());
538 self
539 }
540}
541
542impl Method for GetBotDescription {
543 type Response = BotDescription;
544
545 fn into_payload(self) -> Payload {
546 Payload::json("getMyDescription", self)
547 }
548}
549
550#[serde_with::skip_serializing_none]
552#[derive(Clone, Debug, Default, Serialize)]
553pub struct GetBotName {
554 language_code: Option<String>,
555}
556
557impl GetBotName {
558 pub fn with_language_code<T>(mut self, value: T) -> Self
564 where
565 T: Into<String>,
566 {
567 self.language_code = Some(value.into());
568 self
569 }
570}
571
572impl Method for GetBotName {
573 type Response = BotName;
574
575 fn into_payload(self) -> Payload {
576 Payload::json("getMyName", self)
577 }
578}
579
580#[serde_with::skip_serializing_none]
582#[derive(Clone, Debug, Default, Serialize)]
583pub struct GetBotShortDescription {
584 language_code: Option<String>,
585}
586
587impl GetBotShortDescription {
588 pub fn with_language_code<T>(mut self, value: T) -> Self
594 where
595 T: Into<String>,
596 {
597 self.language_code = Some(value.into());
598 self
599 }
600}
601
602impl Method for GetBotShortDescription {
603 type Response = BotShortDescription;
604
605 fn into_payload(self) -> Payload {
606 Payload::json("getMyShortDescription", self)
607 }
608}
609
610#[derive(Clone, Copy, Debug)]
618pub struct LogOut;
619
620impl Method for LogOut {
621 type Response = bool;
622
623 fn into_payload(self) -> Payload {
624 Payload::empty("logOut")
625 }
626}
627
628#[serde_with::skip_serializing_none]
630#[derive(Clone, Debug, Serialize)]
631pub struct SetBotCommands {
632 commands: Vec<BotCommand>,
633 language_code: Option<String>,
634 scope: Option<BotCommandScope>,
635}
636
637impl SetBotCommands {
638 pub fn new(commands: impl IntoIterator<Item = BotCommand>) -> Self {
644 Self {
645 commands: commands.into_iter().collect(),
646 language_code: None,
647 scope: None,
648 }
649 }
650
651 pub fn with_language_code<T>(mut self, value: T) -> Self
659 where
660 T: Into<String>,
661 {
662 self.language_code = Some(value.into());
663 self
664 }
665
666 pub fn with_scope(mut self, value: BotCommandScope) -> Self {
673 self.scope = Some(value);
674 self
675 }
676}
677
678impl Method for SetBotCommands {
679 type Response = bool;
680
681 fn into_payload(self) -> Payload {
682 Payload::json("setMyCommands", self)
683 }
684}
685
686#[serde_with::skip_serializing_none]
692#[derive(Clone, Copy, Debug, Default, Serialize)]
693pub struct SetBotDefaultAdministratorRights {
694 for_channels: Option<bool>,
695 rights: Option<ChatAdministratorRights>,
696}
697
698impl SetBotDefaultAdministratorRights {
699 pub fn with_for_channels(mut self, value: bool) -> Self {
705 self.for_channels = Some(value);
706 self
707 }
708
709 pub fn with_rights(mut self, value: ChatAdministratorRights) -> Self {
716 self.rights = Some(value);
717 self
718 }
719}
720
721impl Method for SetBotDefaultAdministratorRights {
722 type Response = bool;
723
724 fn into_payload(self) -> Payload {
725 Payload::json("setMyDefaultAdministratorRights", self)
726 }
727}
728
729#[serde_with::skip_serializing_none]
731#[derive(Clone, Debug, Default, Serialize)]
732pub struct SetBotDescription {
733 description: Option<String>,
734 language_code: Option<String>,
735}
736
737impl SetBotDescription {
738 pub fn with_description<T>(mut self, value: T) -> Self
746 where
747 T: Into<String>,
748 {
749 self.description = Some(value.into());
750 self
751 }
752
753 pub fn with_language_code<T>(mut self, value: T) -> Self
761 where
762 T: Into<String>,
763 {
764 self.language_code = Some(value.into());
765 self
766 }
767}
768
769impl Method for SetBotDescription {
770 type Response = bool;
771
772 fn into_payload(self) -> Payload {
773 Payload::json("setMyDescription", self)
774 }
775}
776
777#[serde_with::skip_serializing_none]
779#[derive(Clone, Debug, Default, Serialize)]
780pub struct SetBotName {
781 language_code: Option<String>,
782 name: Option<String>,
783}
784
785impl SetBotName {
786 pub fn with_language_code<T>(mut self, value: T) -> Self
794 where
795 T: Into<String>,
796 {
797 self.language_code = Some(value.into());
798 self
799 }
800
801 pub fn with_name<T>(mut self, value: T) -> Self
809 where
810 T: Into<String>,
811 {
812 self.name = Some(value.into());
813 self
814 }
815}
816
817impl Method for SetBotName {
818 type Response = bool;
819
820 fn into_payload(self) -> Payload {
821 Payload::json("setMyName", self)
822 }
823}
824
825#[serde_with::skip_serializing_none]
828#[derive(Clone, Debug, Default, Serialize)]
829pub struct SetBotShortDescription {
830 language_code: Option<String>,
831 short_description: Option<String>,
832}
833
834impl SetBotShortDescription {
835 pub fn with_language_code<T>(mut self, value: T) -> Self
843 where
844 T: Into<String>,
845 {
846 self.language_code = Some(value.into());
847 self
848 }
849
850 pub fn with_short_description<T>(mut self, value: T) -> Self
858 where
859 T: Into<String>,
860 {
861 self.short_description = Some(value.into());
862 self
863 }
864}
865
866impl Method for SetBotShortDescription {
867 type Response = bool;
868
869 fn into_payload(self) -> Payload {
870 Payload::json("setMyShortDescription", self)
871 }
872}