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};
pub type PredicateFn = Arc<dyn Fn(&Update) -> bool + Send + Sync>;
pub struct TypeHandler {
predicate: PredicateFn,
callback: HandlerCallback,
block: bool,
}
impl TypeHandler {
pub fn new(predicate: PredicateFn, callback: HandlerCallback, block: bool) -> Self {
Self {
predicate,
callback,
block,
}
}
}
impl Handler for TypeHandler {
fn check_update(&self, update: &Update) -> Option<MatchResult> {
if (self.predicate)(update) {
Some(MatchResult::Empty)
} else {
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
}
}
#[cfg(test)]
mod tests {
use super::*;
fn noop_callback() -> HandlerCallback {
Arc::new(|_update, _mr| Box::pin(async { HandlerResult::Continue }))
}
#[test]
fn predicate_true_matches() {
let h = TypeHandler::new(Arc::new(|_u| true), noop_callback(), true);
let update: Update = serde_json::from_str(r#"{"update_id": 1}"#).unwrap();
assert!(h.check_update(&update).is_some());
}
#[test]
fn predicate_false_rejects() {
let h = TypeHandler::new(Arc::new(|_u| false), noop_callback(), true);
let update: Update = serde_json::from_str(r#"{"update_id": 1}"#).unwrap();
assert!(h.check_update(&update).is_none());
}
}