diff --git a/Cargo.toml b/Cargo.toml index aee35fcc..ed919a41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,8 @@ teloxide-macros = { version = "0.4", optional = true } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } +dptree = { git = "https://github.com/p0lunin/dptree", branch = "kiss3" } + tokio = { version = "1.8", features = ["fs"] } tokio-util = "0.6" tokio-stream = "0.1" diff --git a/src/dispatching2/dispatcher.rs b/src/dispatching2/dispatcher.rs new file mode 100644 index 00000000..30167507 --- /dev/null +++ b/src/dispatching2/dispatcher.rs @@ -0,0 +1,44 @@ +use crate::{ + dispatching2::handlers::{Handlers, Replaced, UpdateHandler}, + types, + types::Update, +}; +use dptree::{di::DependencySupplier, Replace}; + +pub struct Dispatcher +where + C: Replace, +{ + handlers: Handlers, +} + +impl Dispatcher +where + C: DependencySupplier + + Send + + Sync + + 'static + + Replace, + IR: Send + Sync + 'static + Replace, + Err: Send + Sync + 'static, +{ + pub fn new() -> Self { + Dispatcher { handlers: Handlers::new() } + } + + pub fn message_handler( + mut self, + handler: UpdateHandler, Err>, + ) -> Self { + self.handlers.message_handler(handler); + self + } + + pub fn edited_message_handler( + mut self, + handler: UpdateHandler, Err>, + ) -> Self { + self.handlers.edited_message_handler(handler); + self + } +} diff --git a/src/dispatching2/handlers.rs b/src/dispatching2/handlers.rs new file mode 100644 index 00000000..d63762ed --- /dev/null +++ b/src/dispatching2/handlers.rs @@ -0,0 +1,57 @@ +use crate::{ + types, + types::{Update, UpdateKind}, +}; +use dptree::{di::DependencySupplier, Handler, Replace}; + +pub type Replaced = >::Out; + +pub struct Handlers +where + C: Replace, +{ + message_handler: UpdateHandler>, + edited_message_handler: UpdateHandler>, +} + +macro_rules! new_handler { + ($kind:ident) => { + dptree::parser(|upd: &Update| match &upd.kind { + UpdateKind::$kind(u) => Some(u.clone()), + _ => None, + }) + }; +} + +impl Handlers +where + C: DependencySupplier + + Send + + Sync + + 'static + + Replace, + IR: Send + Sync + 'static + Replace, + Err: Send + Sync + 'static, +{ + pub fn new() -> Self { + Handlers { + message_handler: new_handler!(Message), + edited_message_handler: new_handler!(EditedMessage), + } + } + + pub fn message_handler(&mut self, handler: UpdateHandler, Err>) { + self.message_handler = self.message_handler.clone().branch(handler); + } + + pub fn edited_message_handler( + &mut self, + handler: UpdateHandler, Err>, + ) { + self.edited_message_handler = self.edited_message_handler.clone().branch(handler); + } +} + +// TODO: it is allowed to return message as answer on telegram request in +// webhooks, so we can allow this too. See more there: https://core.telegram.org/bots/api#making-requests-when-getting-updates +pub type UpdateHandler = Handler<'static, C, Result<(), Err>, IR>; diff --git a/src/dispatching2/mod.rs b/src/dispatching2/mod.rs new file mode 100644 index 00000000..06c2e110 --- /dev/null +++ b/src/dispatching2/mod.rs @@ -0,0 +1,4 @@ +mod dispatcher; +mod handlers; + +pub use dispatcher::Dispatcher; diff --git a/src/lib.rs b/src/lib.rs index d09cda25..047bdb67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,7 @@ pub use dispatching::repls::{ mod logging; pub mod dispatching; +pub mod dispatching2; pub mod error_handlers; pub mod prelude; pub mod utils;