1use std::any::Any;
2use std::rc::Rc;
3use std::sync::Arc;
4
5#[macro_export]
10macro_rules! match_message {
11 ($msg:ident { $( $msg_tt:tt )* }) => {
12 {
13 match_message!(@arm $msg as $( $msg_tt )*);
14 }
15 };
16 (@arm $msg:ident as $msg_ty:ty => $msg_handler:block $(,)?) => {
17 use $crate::AsAny;
18 use ::std::any::Any;
19 if let Ok($msg) = ::std::sync::Arc::clone(&$msg).as_any_arc().downcast::<$msg_ty>() {
20 $msg_handler;
21 }
22 };
23 (@arm $msg:ident as $msg_ty:ty => $msg_handler:expr $(,)?) => {
24 match_message!(@arm $msg as $msg_ty => { $msg_handler; });
25 };
26 (@arm $msg:ident as $msg_ty:ty => $msg_handler:block, $( $msg_tt:tt )*) => {
27 match_message!(@arm $msg as $msg_ty => $msg_handler);
28 match_message!(@arm $msg as $( $msg_tt )*);
29 };
30 (@arm $msg:ident as $msg_ty:ty => $msg_handler:expr, $( $msg_tt:tt )*) => {
31 match_message!(@arm $msg as $msg_ty => { $msg_handler; }, $( $msg_tt )*);
32 };
33}
34
35#[doc(hidden)]
36pub trait AsAny {
37 #[doc(hidden)]
38 fn as_any_ref(&self) -> &dyn Any;
39 #[doc(hidden)]
40 fn as_any_mut(&mut self) -> &mut dyn Any;
41 #[doc(hidden)]
42 fn as_any_box(self: Box<Self>) -> Box<dyn Any>;
43 #[doc(hidden)]
44 fn as_any_rc(self: Rc<Self>) -> Rc<dyn Any>;
45 #[doc(hidden)]
46 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>
47 where
48 Self: Send + Sync;
49}
50
51impl<T: 'static> AsAny for T {
52 fn as_any_ref(&self) -> &dyn Any {
53 self
54 }
55
56 fn as_any_mut(&mut self) -> &mut dyn Any {
57 self
58 }
59
60 fn as_any_box(self: Box<Self>) -> Box<dyn Any> {
61 self
62 }
63
64 fn as_any_rc(self: Rc<Self>) -> Rc<dyn Any> {
65 self
66 }
67
68 fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>
69 where
70 Self: Send + Sync,
71 {
72 self
73 }
74}