spdlog_telegram/
recipient.rs1use std::{borrow::Cow, convert::Infallible};
2
3use serde_json as json;
4
5#[derive(Debug, PartialEq, Eq)]
6enum TargetChatInner {
7 Id(i64),
8 Username(String),
9}
10
11pub(crate) mod __private {
14 use super::*;
15
16 #[derive(Debug, PartialEq, Eq)]
17 pub struct TargetChat(TargetChatInner);
18
19 impl TargetChat {
20 pub(crate) fn id(chat_id: i64) -> Self {
21 Self(TargetChatInner::Id(chat_id))
22 }
23
24 pub(crate) fn username(username: String) -> Self {
25 Self(TargetChatInner::Username(username))
26 }
27
28 pub(crate) fn into_json(self) -> json::Value {
29 match self.0 {
30 TargetChatInner::Id(id) => json::Value::Number(id.into()),
31 TargetChatInner::Username(username) => json::Value::String(username),
32 }
33 }
34 }
35}
36use __private::TargetChat;
37
38#[derive(Debug, PartialEq, Eq)]
43pub struct Recipient {
44 pub(crate) target: TargetChat,
45 pub(crate) thread_id: Option<u64>,
46 pub(crate) reply_to: Option<(u64, Option<TargetChat>)>,
47}
48
49impl Recipient {
50 pub fn builder() -> RecipientBuilder<()> {
52 RecipientBuilder {
53 target: (),
54 thread_id: None,
55 reply_to: None,
56 }
57 }
58
59 pub fn chat_id(chat_id: i64) -> Self {
63 Self::builder().chat_id(chat_id).build()
64 }
65
66 pub fn username<S>(username: S) -> Self
70 where
71 S: Into<String>,
72 {
73 Self::builder().username(username).build()
74 }
75}
76
77impl From<i64> for Recipient {
78 fn from(chat_id: i64) -> Self {
79 Self::chat_id(chat_id)
80 }
81}
82
83macro_rules! impl_from_str_for_recipient {
84 ( $($str_ty:ty),+ ) => {
85 $(impl From<$str_ty> for Recipient {
86 fn from(username: $str_ty) -> Self {
87 Self::username(username)
88 }
89 })+
90 };
91}
92impl_from_str_for_recipient!(&str, &mut str, Box<str>, Cow<'_, str>, String, &String);
93
94pub struct RecipientBuilder<ArgC> {
95 target: ArgC,
96 thread_id: Option<u64>,
97 reply_to: Option<(u64, Option<TargetChat>)>,
98}
99
100impl<ArgC> RecipientBuilder<ArgC> {
101 pub fn chat_id(self, chat_id: i64) -> RecipientBuilder<TargetChat> {
102 RecipientBuilder {
103 target: TargetChat::id(chat_id),
104 thread_id: self.thread_id,
105 reply_to: self.reply_to,
106 }
107 }
108
109 pub fn username<S>(self, username: S) -> RecipientBuilder<TargetChat>
110 where
111 S: Into<String>,
112 {
113 RecipientBuilder {
114 target: TargetChat::username(username.into()),
115 thread_id: self.thread_id,
116 reply_to: self.reply_to,
117 }
118 }
119
120 pub fn thread_id(mut self, thread_id: u64) -> Self {
121 self.thread_id = Some(thread_id);
122 self
123 }
124
125 pub fn reply_to(mut self, message_id: u64) -> Self {
126 self.reply_to = Some((message_id, None));
127 self
128 }
129
130 #[allow(dead_code)]
133 fn reply_to_diff_chat_id(mut self, message_id: u64, chat_id: i64) -> Self {
134 self.reply_to = Some((message_id, Some(TargetChat::id(chat_id))));
135 self
136 }
137
138 #[allow(dead_code)]
140 fn reply_to_diff_username<S>(mut self, message_id: u64, chat_username: S) -> Self
141 where
142 S: Into<String>,
143 {
144 self.reply_to = Some((message_id, Some(TargetChat::username(chat_username.into()))));
145 self
146 }
147}
148
149impl RecipientBuilder<()> {
150 #[doc(hidden)]
151 #[deprecated(note = "\n\n\
152 builder compile-time error:\n\
153 - missing required field `chat_id` or `username`\n\n\
154 ")]
155 pub fn build(self, _: Infallible) {}
156}
157
158impl RecipientBuilder<TargetChat> {
159 pub fn build(self) -> Recipient {
160 Recipient {
161 target: self.target,
162 thread_id: self.thread_id,
163 reply_to: self.reply_to,
164 }
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171
172 #[test]
173 fn from_into() {
174 fn echo(r: impl Into<Recipient>) -> Recipient {
175 r.into()
176 }
177 assert_eq!(echo(-1001234567890), Recipient::chat_id(-1001234567890));
178 assert_eq!(echo("@username"), Recipient::username("@username"));
179 }
180}