use std::collections::HashMap; use serde_json::Value as JsonValue; use std::future::Future; use futures::future::BoxFuture; use log::{ warn, trace }; use crate::client::Client; pub trait Handler: Send + Sync + 'static { fn handle(&self, _: Client, _: JsonValue) -> BoxFuture<'static, ()>; } impl Handler for C where C: Send + Sync + 'static + Fn(Client, JsonValue) -> F, F: Future + 'static + Send { fn handle(&self, client: Client, req: JsonValue) -> BoxFuture<'static, ()> { Box::pin((*self)(client, req)) } } pub struct UpdateRouter { router: HashMap>, rt: tokio::runtime::Handle, } impl UpdateRouter { pub fn new(rt: tokio::runtime::Handle) -> Self { Self { router: HashMap::new(), rt: rt, } } pub fn add_handler(&mut self, update_type: &str, handler: H) { self.router.insert(update_type.to_owned(), Box::new(handler)); } pub fn dispatch(&self, client: &Client, update: JsonValue) { let update_type: &str = update["@type"].as_str().unwrap(); match self.router.get(update_type) { Some(handler) => { self.rt.spawn(handler.handle(client.clone(), update)); }, None => { warn!("no handler for {}", update_type); trace!("request was: {}", update); }, } } }