telegram_client/api/
api.rs

1use std::borrow::Borrow;
2use std::sync::Arc;
3
4use rtdlib::errors::RTDResult;
5use rtdlib::Tdlib;
6use rtdlib::types::RFunction;
7
8use crate::api::aasync::AsyncApi;
9use crate::api::aevent::EventApi;
10
11#[derive(Debug, Clone)]
12pub struct ApiBuilder {
13  inner: Api
14}
15
16impl ApiBuilder {
17  pub fn new() -> Self {
18    Self {
19      inner: Api {
20        tdlib: Arc::new(Tdlib::new()),
21        log: true,
22        unsafe_log: false,
23      }
24    }
25  }
26
27  pub fn build(&self) -> Api {
28    self.inner.clone()
29  }
30
31  fn tdlib(&mut self, tdlib: Tdlib) -> &mut Self {
32    self.inner.tdlib = Arc::new(tdlib);
33    self
34  }
35
36  pub fn log(&mut self, open: bool) -> &mut Self {
37    self.inner.log = open;
38    self
39  }
40
41  pub fn unsafe_log(&mut self, unsafe_log: bool) -> &mut Self {
42    self.inner.unsafe_log = unsafe_log;
43    self
44  }
45}
46
47
48#[derive(Debug, Clone)]
49pub struct Api {
50  tdlib: Arc<Tdlib>,
51  log: bool,
52  unsafe_log: bool,
53}
54
55impl Default for Api {
56  fn default() -> Self {
57    ApiBuilder::new().build()
58  }
59}
60
61
62impl Api {
63  pub fn builder() -> ApiBuilder {
64    ApiBuilder::new()
65  }
66
67  pub fn new(tdlib: Tdlib) -> Self {
68    ApiBuilder::new().tdlib(tdlib).build()
69  }
70
71  pub fn event() -> EventApi {
72    Api::event_with_tdlib(Tdlib::new())
73  }
74
75  pub fn event_with_tdlib(tdlib: Tdlib) -> EventApi {
76    Api::event_with_api(Api::new(tdlib))
77  }
78
79  pub fn event_with_api(api: Api) -> EventApi {
80    EventApi::new(api)
81  }
82
83  pub fn rasync() -> AsyncApi {
84    Api::rasync_with_tdlib(Tdlib::new())
85  }
86
87  pub fn rasync_with_tdlib(tdlib: Tdlib) -> AsyncApi {
88    Api::rasync_with_api(Api::new(tdlib))
89  }
90
91  pub fn rasync_with_api(api: Api) -> AsyncApi {
92    AsyncApi::new(api)
93  }
94
95  pub fn event_api(&self) -> EventApi {
96    Api::event_with_api(self.clone())
97  }
98
99  pub fn rasync_api(&self) -> AsyncApi {
100    Api::rasync_with_api(self.clone())
101  }
102
103  #[doc(hidden)]
104  pub fn tdlib(&self) -> &Tdlib {
105    self.tdlib.borrow()
106  }
107
108  fn safe_log(&self, text: &String) -> String {
109    if self.unsafe_log {
110      return text.clone();
111    }
112    if text.contains("api_id") || text.contains("api_hash") {
113      let regex_api_id = regex::Regex::new(r#"api_id":\d*"#).expect("Regex fail");
114      let hide_api_id = regex_api_id.replace_all(text, r#"api_id":"****""#);
115      let regex_api_hash = regex::Regex::new(r#"api_hash":"[0-9|a-f]*""#).expect("Regex fail");
116      let hide_api_hash = regex_api_hash.replace_all(&hide_api_id, r#"api_hash":"**********""#);
117      hide_api_hash.into_owned()
118    } else {
119      text.clone()
120    }
121  }
122
123  pub fn send<Fnc: RFunction>(&self, fnc: Fnc) -> RTDResult<()> {
124    let json = fnc.to_json()?;
125    if self.log {
126      debug!("===> {}", self.safe_log(&json));
127    }
128    self.tdlib.send(&json[..]);
129    Ok(())
130  }
131
132  pub fn receive(&self, timeout: f64) -> Option<String> {
133    let receive = self.tdlib.receive(timeout);
134    if self.log {
135      if receive.is_some() {
136        debug!("<=== {}", receive.clone().map_or("<NONE>".to_string(), |v| self.safe_log(&v)));
137      }
138    }
139    receive
140  }
141
142  pub fn execute<Fnc: RFunction>(&self, fnc: Fnc) -> RTDResult<Option<String>> {
143    let json = fnc.to_json()?;
144    if self.log {
145      info!("===>>> {}", self.safe_log(&json));
146    }
147    Ok(self.tdlib.execute(&json[..]))
148  }
149}