eventroute/
lib.rs

1use std::{
2    any::{Any, TypeId},
3    collections::HashMap,
4    sync::Arc,
5};
6
7pub trait Handler<T>: 'static {
8    fn call(&self, args: T);
9}
10
11impl<T, S> Handler<S> for Arc<T>
12where
13    T: Handler<S>,
14{
15    fn call(&self, args: S) {
16        self.as_ref().call(args);
17    }
18}
19
20pub struct Source<T: ?Sized> {
21    handler: Arc<dyn Handler<T>>,
22}
23
24impl<T: 'static> Handler<T> for Source<T> {
25    fn call(&self, args: T) {
26        self.handler.call(args);
27    }
28}
29
30#[derive(Default)]
31pub struct Router {
32    handlers: HashMap<TypeId, Box<dyn Any>>,
33}
34
35impl Router {
36    pub fn new() -> Self {
37        Self::default()
38    }
39
40    pub fn on<T, Args>(&mut self, handler: T)
41    where
42        T: Handler<Args>,
43        Args: 'static,
44    {
45        let source = Source {
46            handler: Arc::new(handler),
47        };
48        self.handlers.insert(TypeId::of::<Args>(), Box::new(source));
49    }
50
51    pub fn emit<T: 'static>(&self, event: T) {
52        if let Some(source) = self.source::<T>() {
53            source.call(event);
54        }
55    }
56
57    pub fn source<T: 'static>(&self) -> Option<&Source<T>> {
58        if let Some(source) = self.handlers.get(&TypeId::of::<T>()) {
59            source.downcast_ref::<Source<T>>()
60        } else {
61            None
62        }
63    }
64}
65
66pub fn new() -> Router {
67    Router::new()
68}
69
70impl<Func, T> Handler<T> for Func
71where
72    Func: 'static + Fn(T) -> (),
73{
74    fn call(&self, args: T) {
75        (self)(args);
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    pub struct Test {
84        foo: i32,
85    }
86
87    pub struct Foo {
88        bar: i32,
89    }
90
91    #[test]
92    fn test_router() {
93        let mut router = Router::new();
94        router.on(|i: i32| {
95            println!("{}", i * 10);
96        });
97        router.on(|(a, b): (i32, i32)| {
98            println!("{}", a * b);
99        });
100        router.on(|test: Test| {
101            println!("test {}", test.foo);
102        });
103        router.on(|foo: Foo| {
104            println!("bar {}", foo.bar);
105        });
106
107        router.emit(3);
108        router.emit((2, 3));
109        router.emit(Foo { bar: 232 });
110        router.emit(Test { foo: 232 });
111    }
112}