1pub mod methods;
6pub mod types;
7
8use {
9 reqwest::{
10 header::{HeaderValue, CONTENT_TYPE},
11 multipart::{Form, Part},
12 RequestBuilder, Url,
13 },
14 serde::{
15 de::{DeserializeOwned, Error as _},
16 ser::{Impossible, SerializeStruct},
17 Deserialize, Serialize, Serializer,
18 },
19 std::{
20 borrow::Cow,
21 fmt::{Display, Formatter},
22 future::{Future, IntoFuture},
23 pin::Pin,
24 sync::Arc,
25 },
26 types::ReplyMarkup,
27};
28
29pub const MAX_MSG_LEN: usize = 4096;
30pub type Result<T = (), E = Error> = std::result::Result<T, E>;
31
32trait IsDefault {
33 fn is_default(&self) -> bool;
34}
35
36impl<T> IsDefault for Option<T> {
37 fn is_default(&self) -> bool {
38 self.is_none()
39 }
40}
41
42impl IsDefault for bool {
43 fn is_default(&self) -> bool {
44 !*self
45 }
46}
47
48impl IsDefault for Cow<'_, str> {
49 fn is_default(&self) -> bool {
50 self.is_empty()
51 }
52}
53
54impl<T> IsDefault for Cow<'_, [T]>
55where
56 [T]: ToOwned,
57{
58 fn is_default(&self) -> bool {
59 self.is_empty()
60 }
61}
62
63impl IsDefault for ReplyMarkup<'_> {
64 fn is_default(&self) -> bool {
65 matches!(self, Self::None)
66 }
67}
68
69#[derive(Debug)]
71pub enum Error {
72 Io(std::io::Error),
73 Request { method_name: &'static str, inner: reqwest::Error },
74 Response { method_name: &'static str, description: Box<str> },
75}
76
77impl From<std::io::Error> for Error {
78 fn from(e: std::io::Error) -> Self {
79 Self::Io(e)
80 }
81}
82
83impl Display for Error {
84 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
85 match self {
86 Self::Io(e) => write!(f, "IO error: {e}"),
87 Self::Request { method_name, inner } => {
88 write!(f, "Error while sending `{method_name}`: {inner}")
89 }
90 Self::Response { method_name, description } => {
91 writeln!(f, "Telegram API error from method {method_name}: {description}")
92 }
93 }
94 }
95}
96
97impl std::error::Error for Error {}
98
99pub trait Request: Serialize + IntoFuture<Output = Result<Self::Response>> {
100 const NAME: &str;
101 type Response: DeserializeOwned;
102
103 fn to_future(&self) -> impl Future<Output = Result<Self::Response>>;
112}
113
114#[derive(Deserialize)]
115struct TelegramResponse<T> {
116 ok: bool,
117 #[serde(default)]
118 description: String,
119 result: Option<T>,
120}
121
122fn form_filler_err(s: impl Display) -> serde::de::value::Error {
123 serde::de::value::Error::custom(format_args!("FormFiller::{s}"))
124}
125
126struct StringExtractor;
127
128impl Serializer for StringExtractor {
129 type Ok = String;
130 type Error = std::fmt::Error;
131 type SerializeSeq = Impossible<Self::Ok, std::fmt::Error>;
132 type SerializeTuple = Impossible<Self::Ok, std::fmt::Error>;
133 type SerializeTupleStruct = Impossible<Self::Ok, std::fmt::Error>;
134 type SerializeTupleVariant = Impossible<Self::Ok, std::fmt::Error>;
135 type SerializeMap = Impossible<Self::Ok, std::fmt::Error>;
136 type SerializeStruct = Impossible<Self::Ok, std::fmt::Error>;
137 type SerializeStructVariant = Impossible<Self::Ok, std::fmt::Error>;
138
139 fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
140 Err(std::fmt::Error)
141 }
142
143 fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
144 Err(std::fmt::Error)
145 }
146
147 fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
148 Err(std::fmt::Error)
149 }
150
151 fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
152 Err(std::fmt::Error)
153 }
154
155 fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
156 Err(std::fmt::Error)
157 }
158
159 fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
160 Err(std::fmt::Error)
161 }
162
163 fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
164 Err(std::fmt::Error)
165 }
166
167 fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
168 Err(std::fmt::Error)
169 }
170
171 fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
172 Err(std::fmt::Error)
173 }
174
175 fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
176 Err(std::fmt::Error)
177 }
178
179 fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
180 Err(std::fmt::Error)
181 }
182
183 fn serialize_char(self, c: char) -> Result<Self::Ok, Self::Error> {
184 Ok(c.to_string())
185 }
186
187 fn serialize_str(self, s: &str) -> Result<Self::Ok, Self::Error> {
188 Ok(s.to_owned())
189 }
190
191 fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
192 Err(std::fmt::Error)
193 }
194
195 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
196 Err(std::fmt::Error)
197 }
198
199 fn serialize_some<T: ?Sized + Serialize>(self, x: &T) -> Result<Self::Ok, Self::Error> {
200 x.serialize(self)
201 }
202
203 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
204 Err(std::fmt::Error)
205 }
206
207 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
208 Ok(name.to_owned())
209 }
210
211 fn serialize_unit_variant(
212 self,
213 _: &'static str,
214 _: u32,
215 name: &'static str,
216 ) -> Result<Self::Ok, Self::Error> {
217 Ok(name.to_owned())
218 }
219
220 fn serialize_newtype_struct<T: ?Sized + Serialize>(
221 self,
222 _: &'static str,
223 x: &T,
224 ) -> Result<Self::Ok, Self::Error> {
225 x.serialize(self)
226 }
227
228 fn serialize_newtype_variant<T: ?Sized + Serialize>(
229 self,
230 _: &'static str,
231 _: u32,
232 _: &'static str,
233 x: &T,
234 ) -> Result<Self::Ok, Self::Error> {
235 x.serialize(self)
236 }
237
238 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
239 Err(std::fmt::Error)
240 }
241
242 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
243 Err(std::fmt::Error)
244 }
245
246 fn serialize_tuple_struct(
247 self,
248 _: &'static str,
249 _: usize,
250 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
251 Err(std::fmt::Error)
252 }
253
254 fn serialize_tuple_variant(
255 self,
256 _: &'static str,
257 _: u32,
258 _: &'static str,
259 _: usize,
260 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
261 Err(std::fmt::Error)
262 }
263
264 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
265 Err(std::fmt::Error)
266 }
267
268 fn serialize_struct(
269 self,
270 _: &'static str,
271 _: usize,
272 ) -> Result<Self::SerializeStruct, Self::Error> {
273 Err(std::fmt::Error)
274 }
275
276 fn serialize_struct_variant(
277 self,
278 _: &'static str,
279 _: u32,
280 _: &'static str,
281 _: usize,
282 ) -> Result<Self::SerializeStructVariant, Self::Error> {
283 Err(std::fmt::Error)
284 }
285}
286
287fn get_string<T: ?Sized + Serialize>(value: &T) -> Result<String, &T> {
288 value.serialize(StringExtractor).map_err(|_| value)
289}
290
291struct FormFiller(Option<Form>);
292
293impl SerializeStruct for FormFiller {
294 type Ok = Form;
295 type Error = serde::de::value::Error;
296
297 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
298 where
299 T: ?Sized + Serialize,
300 {
301 let json = get_string(value) .map_or_else(serde_json::to_string, Ok)
303 .map_err(|e| {
304 form_filler_err(format_args!("serialize_field: JSON serializer failed: {e}"))
305 })?;
306 self.0 = self
307 .0
308 .take()
309 .ok_or(form_filler_err("serialize_field: form lost"))?
310 .text(key, json)
311 .into();
312 Ok(())
313 }
314
315 fn end(self) -> Result<Self::Ok, Self::Error> {
316 self.0.ok_or(form_filler_err("end: form lost"))
317 }
318}
319
320fn e<T>() -> Result<T, serde::de::value::Error> {
321 Err(serde::de::value::Error::custom("FormFiller failed: Request must be a struct"))
322}
323
324impl Serializer for FormFiller {
325 type Ok = Form;
326 type Error = serde::de::value::Error;
327 type SerializeSeq = Impossible<Self::Ok, Self::Error>;
328 type SerializeTuple = Impossible<Self::Ok, Self::Error>;
329 type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
330 type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
331 type SerializeMap = Impossible<Self::Ok, Self::Error>;
332 type SerializeStruct = Self;
333 type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
334
335 fn serialize_struct(self, _: &str, _: usize) -> Result<Self::SerializeStruct, Self::Error> {
336 Ok(self)
337 }
338
339 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
340 e()
341 }
342 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
343 e()
344 }
345 fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
346 e()
347 }
348 fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
349 e()
350 }
351 fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
352 e()
353 }
354 fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
355 e()
356 }
357 fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
358 e()
359 }
360 fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
361 e()
362 }
363 fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
364 e()
365 }
366 fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
367 e()
368 }
369 fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
370 e()
371 }
372 fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
373 e()
374 }
375 fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
376 e()
377 }
378 fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
379 e()
380 }
381 fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
382 e()
383 }
384 fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
385 e()
386 }
387 fn serialize_unit_struct(self, _: &str) -> Result<Self::Ok, Self::Error> {
388 e()
389 }
390 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
391 e()
392 }
393 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
394 e()
395 }
396 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
397 e()
398 }
399 fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<Self::Ok, Self::Error> {
400 e()
401 }
402 fn serialize_unit_variant(self, _: &str, _: u32, _: &str) -> Result<Self::Ok, Self::Error> {
403 e()
404 }
405 fn serialize_tuple_struct(
406 self,
407 _: &str,
408 _: usize,
409 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
410 e()
411 }
412 fn serialize_newtype_struct<T: ?Sized + Serialize>(
413 self,
414 _: &str,
415 _: &T,
416 ) -> Result<Self::Ok, Self::Error> {
417 e()
418 }
419 fn serialize_tuple_variant(
420 self,
421 _: &str,
422 _: u32,
423 _: &str,
424 _: usize,
425 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
426 e()
427 }
428 fn serialize_struct_variant(
429 self,
430 _: &str,
431 _: u32,
432 _: &str,
433 _: usize,
434 ) -> Result<Self::SerializeStructVariant, Self::Error> {
435 e()
436 }
437 fn serialize_newtype_variant<T: ?Sized + Serialize>(
438 self,
439 _: &str,
440 _: u32,
441 _: &str,
442 _: &T,
443 ) -> Result<Self::Ok, Self::Error> {
444 e()
445 }
446}
447
448pub(crate) const PAYLOAD_NAME: &str = "__PAYLOAD";
449pub(crate) const PAYLOAD_LINK: &str = "attach://__PAYLOAD";
450
451pub(crate) fn serialise_into_form<R: Serialize>(req: &R, payload: Part) -> Form {
452 req.serialize(FormFiller(Some(Form::new())))
453 .expect("request to be a struct")
454 .part(PAYLOAD_NAME, payload)
455}
456
457pub(crate) trait Multipart {
458 fn get_payload(&self) -> Option<Part>;
459 fn get_payload_mut(&mut self) -> Option<Part>;
464}
465
466pub struct BotBuilder<'src> {
469 token: &'src str,
470 api_url: Option<Url>,
471 client: Option<reqwest::Client>,
472}
473
474impl<'src> BotBuilder<'src> {
475 pub fn new(token: &'src str) -> Self {
477 Self { token, api_url: None, client: None }
478 }
479
480 pub fn api_url(mut self, base: impl reqwest::IntoUrl) -> reqwest::Result<Self> {
484 self.api_url = Some(base.into_url()?);
485 Ok(self)
486 }
487
488 pub fn set_api_url(&mut self, base: impl reqwest::IntoUrl) -> reqwest::Result<()> {
492 self.api_url = Some(base.into_url()?);
493 Ok(())
494 }
495
496 pub fn client(mut self, client: reqwest::Client) -> Self {
500 self.client = Some(client);
501 self
502 }
503
504 pub fn set_client(&mut self, client: reqwest::Client) {
508 self.client = Some(client);
509 }
510
511 pub fn token(mut self, token: &'src str) -> Self {
513 self.token = token;
514 self
515 }
516
517 pub fn set_token(&mut self, token: &'src str) {
519 self.token = token;
520 }
521
522 pub fn build(self) -> Bot {
524 let mut base =
525 self.api_url.unwrap_or_else(|| Url::parse("https://api.telegram.org").unwrap());
526 base.set_path(&format!("bot{}", self.token));
527 Bot(Arc::new((self.client.unwrap_or_default(), base)))
528 }
529}
530
531#[derive(Clone)]
533pub struct Bot(Arc<(reqwest::Client, Url)>);
534
535impl Bot {
536 pub fn new(token: &str) -> Self {
540 BotBuilder::new(token).build()
541 }
542
543 fn client(&self) -> &reqwest::Client {
544 &self.0 .0
545 }
546
547 fn base(&self) -> &Url {
548 &self.0 .1
549 }
550
551 pub fn multipart_request<R: DeserializeOwned + 'static>(
561 &self,
562 method_name: &'static str,
563 form: Form,
564 ) -> Pin<Box<dyn Future<Output = Result<R>> + Send + Sync + 'static>> {
565 let mut url = self.base().clone();
566 if let Ok(mut segments) = url.path_segments_mut() {
567 segments.push(method_name);
568 }
569 let req = self.client().get(url).multipart(form);
570
571 Box::pin(Self::prepared_request(method_name, req))
572 }
573
574 pub fn request<R: DeserializeOwned + 'static>(
582 &self,
583 method_name: &'static str,
584 json: String,
585 ) -> Pin<Box<dyn Future<Output = Result<R>> + Send + Sync + 'static>> {
586 let mut url = self.base().clone();
587 if let Ok(mut segments) = url.path_segments_mut() {
588 segments.push(method_name);
589 }
590 let req = self
591 .client()
592 .get(url)
593 .body(json)
594 .header(CONTENT_TYPE, const { HeaderValue::from_static("application/json") });
595
596 Box::pin(Self::prepared_request(method_name, req))
597 }
598
599 async fn prepared_request<R: DeserializeOwned>(
600 method_name: &'static str,
601 req: RequestBuilder,
602 ) -> Result<R> {
603 let (client, req) = req.build_split();
604 let req = req.map_err(|inner| Error::Request { method_name, inner })?;
605
606 match client
607 .execute(req)
608 .await
609 .map_err(|inner| Error::Request { method_name, inner })?
610 .json()
611 .await
612 .map_err(|inner| Error::Request { method_name, inner })?
613 {
614 TelegramResponse { ok: true, result: Some(result), .. } => Ok(result),
615 TelegramResponse { mut description, .. } => Err({
616 description.insert_str(0, ": Telegram API error: ");
617 description.insert_str(0, method_name);
618 crate::Error::Response { method_name, description: description.into() }
619 }),
620 }
621 }
622}