use std::collections::HashSet;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use rust_tg_bot_raw::types::update::Update;
use super::base::{Handler, HandlerCallback, HandlerResult, MatchResult};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ChatBoostType {
ChatBoost,
RemovedChatBoost,
Any,
}
pub struct ChatBoostHandler {
callback: HandlerCallback,
boost_type: ChatBoostType,
chat_ids: HashSet<i64>,
chat_usernames: HashSet<String>,
block: bool,
}
impl ChatBoostHandler {
pub fn new(
callback: HandlerCallback,
boost_type: ChatBoostType,
chat_ids: HashSet<i64>,
chat_usernames: HashSet<String>,
block: bool,
) -> Self {
let chat_usernames = chat_usernames
.into_iter()
.map(|u| u.trim_start_matches('@').to_lowercase())
.collect();
Self {
callback,
boost_type,
chat_ids,
chat_usernames,
block,
}
}
}
impl Handler for ChatBoostHandler {
fn check_update(&self, update: &Update) -> Option<MatchResult> {
let has_boost = update.chat_boost().is_some();
let has_removed = update.removed_chat_boost().is_some();
if !has_boost && !has_removed {
return None;
}
match self.boost_type {
ChatBoostType::ChatBoost => {
if !has_boost {
return None;
}
}
ChatBoostType::RemovedChatBoost => {
if !has_removed {
return None;
}
}
ChatBoostType::Any => {}
}
if self.chat_ids.is_empty() && self.chat_usernames.is_empty() {
return Some(MatchResult::Empty);
}
if let Some(chat) = update.effective_chat() {
if self.chat_ids.contains(&chat.id) {
return Some(MatchResult::Empty);
}
if let Some(ref uname) = chat.username {
if self.chat_usernames.contains(&uname.to_lowercase()) {
return Some(MatchResult::Empty);
}
}
}
None
}
fn handle_update(
&self,
update: Arc<Update>,
match_result: MatchResult,
) -> Pin<Box<dyn Future<Output = HandlerResult> + Send>> {
(self.callback)(update, match_result)
}
fn block(&self) -> bool {
self.block
}
}