telegram_client/api/
api.rs1use 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}