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}