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