rust_tg_bot_ext/
defaults.rs1use std::collections::HashMap;
25
26use serde_json::Value;
27
28use rust_tg_bot_raw::types::link_preview_options::LinkPreviewOptions;
29
30#[derive(Debug, Clone)]
35pub struct Defaults {
36 parse_mode: Option<String>,
37 disable_notification: Option<bool>,
38 allow_sending_without_reply: Option<bool>,
39 protect_content: Option<bool>,
40 block: bool,
41 link_preview_options: Option<LinkPreviewOptions>,
42 do_quote: Option<bool>,
43 api_defaults: HashMap<String, Value>,
46}
47
48impl Defaults {
49 #[must_use]
57 pub(crate) fn new(
58 parse_mode: Option<String>,
59 disable_notification: Option<bool>,
60 allow_sending_without_reply: Option<bool>,
61 protect_content: Option<bool>,
62 block: Option<bool>,
63 link_preview_options: Option<LinkPreviewOptions>,
64 do_quote: Option<bool>,
65 ) -> Self {
66 let block = block.unwrap_or(true);
67
68 let mut api_defaults = HashMap::new();
69
70 if let Some(ref pm) = parse_mode {
71 let v = Value::String(pm.clone());
72 api_defaults.insert("parse_mode".into(), v.clone());
73 api_defaults.insert("explanation_parse_mode".into(), v.clone());
74 api_defaults.insert("text_parse_mode".into(), v.clone());
75 api_defaults.insert("question_parse_mode".into(), v);
76 }
77 if let Some(dn) = disable_notification {
78 api_defaults.insert("disable_notification".into(), Value::Bool(dn));
79 }
80 if let Some(aswr) = allow_sending_without_reply {
81 api_defaults.insert("allow_sending_without_reply".into(), Value::Bool(aswr));
82 }
83 if let Some(pc) = protect_content {
84 api_defaults.insert("protect_content".into(), Value::Bool(pc));
85 }
86 if let Some(dq) = do_quote {
87 api_defaults.insert("do_quote".into(), Value::Bool(dq));
88 }
89 if let Some(ref lpo) = link_preview_options {
90 if let Ok(v) = serde_json::to_value(lpo) {
91 api_defaults.insert("link_preview_options".into(), v);
92 }
93 }
94
95 Self {
96 parse_mode,
97 disable_notification,
98 allow_sending_without_reply,
99 protect_content,
100 block,
101 link_preview_options,
102 do_quote,
103 api_defaults,
104 }
105 }
106
107 #[must_use]
119 pub fn builder() -> DefaultsBuilder {
120 DefaultsBuilder::new()
121 }
122
123 #[must_use]
128 pub fn parse_mode(&self) -> Option<&str> {
129 self.parse_mode.as_deref()
130 }
131
132 #[must_use]
135 pub fn explanation_parse_mode(&self) -> Option<&str> {
136 self.parse_mode.as_deref()
137 }
138
139 #[must_use]
142 pub fn text_parse_mode(&self) -> Option<&str> {
143 self.parse_mode.as_deref()
144 }
145
146 #[must_use]
148 pub fn question_parse_mode(&self) -> Option<&str> {
149 self.parse_mode.as_deref()
150 }
151
152 #[must_use]
154 pub fn quote_parse_mode(&self) -> Option<&str> {
155 self.parse_mode.as_deref()
156 }
157
158 #[must_use]
160 pub fn disable_notification(&self) -> Option<bool> {
161 self.disable_notification
162 }
163
164 #[must_use]
167 pub fn allow_sending_without_reply(&self) -> Option<bool> {
168 self.allow_sending_without_reply
169 }
170
171 #[must_use]
173 pub fn block(&self) -> bool {
174 self.block
175 }
176
177 #[must_use]
179 pub fn protect_content(&self) -> Option<bool> {
180 self.protect_content
181 }
182
183 #[must_use]
185 pub fn link_preview_options(&self) -> Option<&LinkPreviewOptions> {
186 self.link_preview_options.as_ref()
187 }
188
189 #[must_use]
191 pub fn do_quote(&self) -> Option<bool> {
192 self.do_quote
193 }
194
195 #[must_use]
197 pub fn api_defaults(&self) -> &HashMap<String, Value> {
198 &self.api_defaults
199 }
200}
201
202impl PartialEq for Defaults {
203 fn eq(&self, other: &Self) -> bool {
204 self.parse_mode == other.parse_mode
205 && self.disable_notification == other.disable_notification
206 && self.allow_sending_without_reply == other.allow_sending_without_reply
207 && self.protect_content == other.protect_content
208 && self.block == other.block
209 && self.link_preview_options == other.link_preview_options
210 && self.do_quote == other.do_quote
211 }
212}
213
214impl Eq for Defaults {}
215
216impl std::hash::Hash for Defaults {
217 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
218 self.parse_mode.hash(state);
219 self.disable_notification.hash(state);
220 self.allow_sending_without_reply.hash(state);
221 self.protect_content.hash(state);
222 self.block.hash(state);
223 self.do_quote.hash(state);
224 if let Some(ref lpo) = self.link_preview_options {
226 if let Ok(v) = serde_json::to_string(lpo) {
227 v.hash(state);
228 }
229 }
230 }
231}
232
233#[derive(Debug)]
256pub struct DefaultsBuilder {
257 parse_mode: Option<String>,
258 disable_notification: Option<bool>,
259 allow_sending_without_reply: Option<bool>,
260 protect_content: Option<bool>,
261 block: Option<bool>,
262 link_preview_options: Option<LinkPreviewOptions>,
263 do_quote: Option<bool>,
264}
265
266impl Default for DefaultsBuilder {
267 fn default() -> Self {
268 Self::new()
269 }
270}
271
272impl DefaultsBuilder {
273 #[must_use]
275 pub fn new() -> Self {
276 Self {
277 parse_mode: None,
278 disable_notification: None,
279 allow_sending_without_reply: None,
280 protect_content: None,
281 block: None,
282 link_preview_options: None,
283 do_quote: None,
284 }
285 }
286
287 #[must_use]
289 pub fn parse_mode(mut self, mode: impl Into<String>) -> Self {
290 self.parse_mode = Some(mode.into());
291 self
292 }
293
294 #[must_use]
296 pub fn disable_notification(mut self, value: bool) -> Self {
297 self.disable_notification = Some(value);
298 self
299 }
300
301 #[must_use]
303 pub fn allow_sending_without_reply(mut self, value: bool) -> Self {
304 self.allow_sending_without_reply = Some(value);
305 self
306 }
307
308 #[must_use]
310 pub fn protect_content(mut self, value: bool) -> Self {
311 self.protect_content = Some(value);
312 self
313 }
314
315 #[must_use]
317 pub fn block(mut self, value: bool) -> Self {
318 self.block = Some(value);
319 self
320 }
321
322 #[must_use]
324 pub fn link_preview_options(mut self, options: LinkPreviewOptions) -> Self {
325 self.link_preview_options = Some(options);
326 self
327 }
328
329 #[must_use]
331 pub fn do_quote(mut self, value: bool) -> Self {
332 self.do_quote = Some(value);
333 self
334 }
335
336 #[must_use]
338 pub fn build(self) -> Defaults {
339 Defaults::new(
340 self.parse_mode,
341 self.disable_notification,
342 self.allow_sending_without_reply,
343 self.protect_content,
344 self.block,
345 self.link_preview_options,
346 self.do_quote,
347 )
348 }
349}
350
351#[cfg(test)]
352mod tests {
353 use super::*;
354
355 #[test]
356 fn defaults_immutable_accessors() {
357 let d = Defaults::builder()
358 .parse_mode("HTML")
359 .disable_notification(true)
360 .allow_sending_without_reply(false)
361 .do_quote(true)
362 .build();
363
364 assert_eq!(d.parse_mode(), Some("HTML"));
365 assert_eq!(d.explanation_parse_mode(), Some("HTML"));
366 assert_eq!(d.text_parse_mode(), Some("HTML"));
367 assert_eq!(d.question_parse_mode(), Some("HTML"));
368 assert_eq!(d.disable_notification(), Some(true));
369 assert_eq!(d.allow_sending_without_reply(), Some(false));
370 assert!(d.block());
371 assert_eq!(d.protect_content(), None);
372 assert_eq!(d.do_quote(), Some(true));
373 }
374
375 #[test]
376 fn defaults_api_defaults_map() {
377 let d = Defaults::builder()
378 .parse_mode("MarkdownV2")
379 .protect_content(true)
380 .build();
381
382 let m = d.api_defaults();
383 assert!(m.contains_key("parse_mode"));
384 assert!(m.contains_key("explanation_parse_mode"));
385 assert!(m.contains_key("protect_content"));
386 assert!(!m.contains_key("disable_notification"));
387 }
388
389 #[test]
390 fn defaults_equality() {
391 let a = Defaults::builder().parse_mode("HTML").build();
392 let b = Defaults::builder().parse_mode("HTML").build();
393 let c = Defaults::builder().build();
394 assert_eq!(a, b);
395 assert_ne!(a, c);
396 }
397
398 #[test]
399 fn block_defaults_to_true() {
400 let d = Defaults::builder().build();
401 assert!(d.block());
402 }
403
404 #[test]
405 fn block_can_be_set_to_false() {
406 let d = Defaults::builder().block(false).build();
407 assert!(!d.block());
408 }
409
410 #[test]
411 fn builder_default_trait() {
412 let b = DefaultsBuilder::default();
413 let d = b.build();
414 assert!(d.parse_mode().is_none());
415 assert!(d.block());
416 }
417}