1use std::fmt;
2use std::ops::Deref;
3
4use serde::ser::{Serialize, Serializer};
5
6use crate::types::*;
7
8macro_rules! integer_id_impls {
9 ($name: ident) => {
10 impl $name {
11 pub fn new(inner: Integer) -> Self {
12 $name(inner)
13 }
14 }
15
16 impl ::std::fmt::Display for $name {
17 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
18 self.0.fmt(f)
19 }
20 }
21
22 impl From<Integer> for $name {
23 fn from(inner: Integer) -> Self {
24 $name::new(inner)
25 }
26 }
27
28 impl From<$name> for Integer {
29 fn from(from: $name) -> Self {
30 from.0
31 }
32 }
33
34 impl<'de> ::serde::de::Deserialize<'de> for $name {
35 fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
36 where
37 D: ::serde::de::Deserializer<'de>,
38 {
39 let inner = ::serde::de::Deserialize::deserialize(deserializer)?;
40 Ok($name::new(inner))
41 }
42 }
43
44 impl ::serde::ser::Serialize for $name {
45 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
46 where
47 S: ::serde::ser::Serializer,
48 {
49 serializer.serialize_i64(self.0)
50 }
51 }
52 };
53}
54
55pub trait ToSourceChat {
57 fn to_source_chat(&self) -> ChatId;
58}
59
60impl<S> ToSourceChat for S
61where
62 S: Deref,
63 S::Target: ToSourceChat,
64{
65 fn to_source_chat(&self) -> ChatId {
66 self.deref().to_source_chat()
67 }
68}
69
70impl ToSourceChat for Message {
71 fn to_source_chat(&self) -> ChatId {
72 self.chat.id()
73 }
74}
75
76impl ToSourceChat for ChannelPost {
77 fn to_source_chat(&self) -> ChatId {
78 self.chat.id.into()
79 }
80}
81
82impl ToSourceChat for MessageOrChannelPost {
83 fn to_source_chat(&self) -> ChatId {
84 match self {
85 &MessageOrChannelPost::Message(ref message) => message.to_source_chat(),
86 &MessageOrChannelPost::ChannelPost(ref channel_post) => channel_post.to_source_chat(),
87 }
88 }
89}
90
91#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
94pub enum ChatRef {
95 Id(ChatId),
96 #[doc(hidden)]
97 ChannelUsername(String),
98}
99
100impl ChatRef {
101 pub fn from_chat_id(chat_id: ChatId) -> ChatRef {
102 ChatRef::Id(chat_id)
103 }
104}
105
106pub trait ToChatRef {
108 fn to_chat_ref(&self) -> ChatRef;
109}
110
111impl<S> ToChatRef for S
112where
113 S: Deref,
114 S::Target: ToChatRef,
115{
116 fn to_chat_ref(&self) -> ChatRef {
117 self.deref().to_chat_ref()
118 }
119}
120
121impl ToChatRef for ChatRef {
122 fn to_chat_ref(&self) -> ChatRef {
123 self.clone()
124 }
125}
126
127impl ToChatRef for Chat {
128 fn to_chat_ref(&self) -> ChatRef {
129 self.id().to_chat_ref()
130 }
131}
132
133impl ToChatRef for MessageChat {
134 fn to_chat_ref(&self) -> ChatRef {
135 self.id().to_chat_ref()
136 }
137}
138
139impl ToChatRef for ChatMember {
140 fn to_chat_ref(&self) -> ChatRef {
141 self.user.to_chat_ref()
142 }
143}
144
145impl ToChatRef for ForwardFrom {
146 fn to_chat_ref(&self) -> ChatRef {
147 match *self {
148 ForwardFrom::User { ref user, .. } => user.to_chat_ref(),
149 ForwardFrom::Channel { ref channel, .. } => channel.to_chat_ref(),
150 ForwardFrom::ChannelHiddenUser { ref sender_name } => {
151 ChatRef::ChannelUsername(sender_name.clone())
152 }
153 }
154 }
155}
156
157impl ToChatRef for Forward {
158 fn to_chat_ref(&self) -> ChatRef {
159 self.from.to_chat_ref()
160 }
161}
162
163impl Serialize for ChatRef {
164 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165 where
166 S: Serializer,
167 {
168 match *self {
169 ChatRef::Id(id) => serializer.serialize_i64(id.into()),
170 ChatRef::ChannelUsername(ref username) => serializer.serialize_str(&username),
171 }
172 }
173}
174
175impl fmt::Display for ChatRef {
176 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
177 match *self {
178 ChatRef::Id(id) => write!(f, "{}", id),
179 ChatRef::ChannelUsername(ref username) => write!(f, "{}", username),
180 }
181 }
182}
183
184macro_rules! chat_id_impls {
185 ($id: ident) => {
186 integer_id_impls!($id);
187
188 impl ToChatRef for $id {
189 fn to_chat_ref(&self) -> ChatRef {
190 ChatRef::from_chat_id((*self).into())
191 }
192 }
193 };
194}
195
196macro_rules! specific_chat_id_impls {
197 ($id: ident, $typ: ident) => {
198 chat_id_impls!($id);
199
200 impl From<$id> for ChatId {
201 fn from(c: $id) -> Self {
202 ChatId::new(c.into())
203 }
204 }
205
206 impl ToChatRef for $typ {
207 fn to_chat_ref(&self) -> ChatRef {
208 self.id.to_chat_ref()
209 }
210 }
211 };
212}
213
214pub trait ToUserId {
216 fn to_user_id(&self) -> UserId;
217}
218
219impl<S> ToUserId for S
220where
221 S: Deref,
222 S::Target: ToUserId,
223{
224 fn to_user_id(&self) -> UserId {
225 self.deref().to_user_id()
226 }
227}
228
229impl ToUserId for UserId {
230 fn to_user_id(&self) -> UserId {
231 *self
232 }
233}
234
235impl ToUserId for ChatMember {
236 fn to_user_id(&self) -> UserId {
237 self.user.id
238 }
239}
240
241impl ToUserId for User {
242 fn to_user_id(&self) -> UserId {
243 self.id
244 }
245}
246
247#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
249pub struct UserId(Integer);
250specific_chat_id_impls!(UserId, User);
251
252#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
254pub struct GroupId(Integer);
255specific_chat_id_impls!(GroupId, Group);
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
259pub struct SupergroupId(Integer);
260specific_chat_id_impls!(SupergroupId, Supergroup);
261
262#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
264pub struct ChannelId(Integer);
265specific_chat_id_impls!(ChannelId, Channel);
266
267#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
269pub struct ChatId(Integer);
270chat_id_impls!(ChatId);
271
272pub trait ToMessageId {
274 fn to_message_id(&self) -> MessageId;
275}
276
277impl<S> ToMessageId for S
278where
279 S: Deref,
280 S::Target: ToMessageId,
281{
282 fn to_message_id(&self) -> MessageId {
283 self.deref().to_message_id()
284 }
285}
286
287impl ToMessageId for MessageId {
288 fn to_message_id(&self) -> MessageId {
289 *self
290 }
291}
292
293impl ToMessageId for Message {
294 fn to_message_id(&self) -> MessageId {
295 self.id
296 }
297}
298
299impl ToMessageId for ChannelPost {
300 fn to_message_id(&self) -> MessageId {
301 self.id
302 }
303}
304
305impl ToMessageId for MessageOrChannelPost {
306 fn to_message_id(&self) -> MessageId {
307 match self {
308 &MessageOrChannelPost::Message(ref message) => message.to_message_id(),
309 &MessageOrChannelPost::ChannelPost(ref channel_post) => channel_post.to_message_id(),
310 }
311 }
312}
313
314#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
316pub struct MessageId(Integer);
317integer_id_impls!(MessageId);
318
319pub trait ToFileRef {
321 fn to_file_ref(&self) -> FileRef;
322}
323
324impl<S> ToFileRef for S
325where
326 S: Deref,
327 S::Target: ToFileRef,
328{
329 fn to_file_ref(&self) -> FileRef {
330 self.deref().to_file_ref()
331 }
332}
333
334macro_rules! file_id_impls {
335 ($name: ident) => {
336 impl ToFileRef for $name {
337 fn to_file_ref(&self) -> FileRef {
338 self.file_id.clone().into()
339 }
340 }
341 };
342}
343
344file_id_impls!(PhotoSize);
345file_id_impls!(Audio);
346file_id_impls!(Document);
347file_id_impls!(Sticker);
348file_id_impls!(Video);
349file_id_impls!(Voice);
350file_id_impls!(VideoNote);
351
352#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
354pub struct FileRef {
355 pub(crate) inner: String,
356}
357
358impl<'a> From<&'a str> for FileRef {
359 fn from(s: &'a str) -> Self {
360 FileRef {
361 inner: s.to_string(),
362 }
363 }
364}
365
366impl<'a> From<String> for FileRef {
367 fn from(s: String) -> Self {
368 FileRef { inner: s.clone() }
369 }
370}
371
372impl Serialize for FileRef {
373 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
374 where
375 S: Serializer,
376 {
377 serializer.serialize_str(&self.inner)
378 }
379}
380
381pub trait ToCallbackQueryId {
383 fn to_callback_query_id(&self) -> CallbackQueryId;
384}
385
386impl<S> ToCallbackQueryId for S
387where
388 S: Deref,
389 S::Target: ToCallbackQueryId,
390{
391 fn to_callback_query_id(&self) -> CallbackQueryId {
392 self.deref().to_callback_query_id()
393 }
394}
395
396impl ToCallbackQueryId for CallbackQuery {
397 fn to_callback_query_id(&self) -> CallbackQueryId {
398 self.id.clone()
399 }
400}
401
402#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
404pub struct CallbackQueryId(String);
405
406#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
407pub struct InlineQueryId(String);