lps/
util.rs

1use std::any::Any;
2use std::rc::Rc;
3use std::sync::Arc;
4
5/// Downcasts [`Arc<dyn Message>`] to the one of the given types and runs the code
6/// which corresponds to it.
7///
8/// [`Arc<dyn Message>`]: crate::message::Message
9#[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}