rust_tg_bot_ext/handlers/
chat_boost.rs1use std::collections::HashSet;
8use std::future::Future;
9use std::pin::Pin;
10use std::sync::Arc;
11
12use rust_tg_bot_raw::types::update::Update;
13
14use super::base::{Handler, HandlerCallback, HandlerResult, MatchResult};
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18#[non_exhaustive]
19pub enum ChatBoostType {
20 ChatBoost,
22 RemovedChatBoost,
24 Any,
26}
27
28pub struct ChatBoostHandler {
30 callback: HandlerCallback,
31 boost_type: ChatBoostType,
32 chat_ids: HashSet<i64>,
33 chat_usernames: HashSet<String>,
34 block: bool,
35}
36
37impl ChatBoostHandler {
38 pub fn new(
40 callback: HandlerCallback,
41 boost_type: ChatBoostType,
42 chat_ids: HashSet<i64>,
43 chat_usernames: HashSet<String>,
44 block: bool,
45 ) -> Self {
46 let chat_usernames = chat_usernames
47 .into_iter()
48 .map(|u| u.trim_start_matches('@').to_lowercase())
49 .collect();
50 Self {
51 callback,
52 boost_type,
53 chat_ids,
54 chat_usernames,
55 block,
56 }
57 }
58}
59
60impl Handler for ChatBoostHandler {
61 fn check_update(&self, update: &Update) -> Option<MatchResult> {
62 let has_boost = update.chat_boost().is_some();
63 let has_removed = update.removed_chat_boost().is_some();
64
65 if !has_boost && !has_removed {
66 return None;
67 }
68
69 match self.boost_type {
70 ChatBoostType::ChatBoost => {
71 if !has_boost {
72 return None;
73 }
74 }
75 ChatBoostType::RemovedChatBoost => {
76 if !has_removed {
77 return None;
78 }
79 }
80 ChatBoostType::Any => {}
81 }
82
83 if self.chat_ids.is_empty() && self.chat_usernames.is_empty() {
85 return Some(MatchResult::Empty);
86 }
87
88 if let Some(chat) = update.effective_chat() {
90 if self.chat_ids.contains(&chat.id) {
91 return Some(MatchResult::Empty);
92 }
93 if let Some(ref uname) = chat.username {
94 if self.chat_usernames.contains(&uname.to_lowercase()) {
95 return Some(MatchResult::Empty);
96 }
97 }
98 }
99
100 None
101 }
102
103 fn handle_update(
104 &self,
105 update: Arc<Update>,
106 match_result: MatchResult,
107 ) -> Pin<Box<dyn Future<Output = HandlerResult> + Send>> {
108 (self.callback)(update, match_result)
109 }
110
111 fn block(&self) -> bool {
112 self.block
113 }
114}