mm1_core/
message.rs

1use std::any::{Any, TypeId};
2use std::fmt;
3
4pub use mm1_proto::Message;
5
6pub struct AnyMessage {
7    message: Box<dyn Any + Send + 'static>,
8    info:    TypeInfo,
9}
10
11struct TypeInfo {
12    id:   TypeId,
13    name: &'static str,
14}
15
16impl AnyMessage {
17    pub fn new<T>(value: T) -> Self
18    where
19        T: Message,
20    {
21        let info = TypeInfo {
22            id:   std::any::TypeId::of::<T>(),
23            name: std::any::type_name::<T>(),
24        };
25        let message = Box::new(value);
26        Self { info, message }
27    }
28
29    pub fn peek<T>(&self) -> Option<&T>
30    where
31        T: Message,
32    {
33        self.message.downcast_ref()
34    }
35
36    pub fn cast<T>(self) -> Result<T, Self>
37    where
38        T: Message,
39    {
40        let Self { message, info } = self;
41        message
42            .downcast()
43            .map(|b| *b)
44            .map_err(move |message| Self { info, message })
45    }
46
47    pub fn is<T>(&self) -> bool
48    where
49        T: Message,
50    {
51        self.message.is::<T>()
52    }
53
54    pub fn tid(&self) -> TypeId {
55        self.info.id
56    }
57
58    pub fn type_name(&self) -> &'static str {
59        self.info.name
60    }
61}
62
63impl fmt::Debug for AnyMessage {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        f.debug_struct("AnyMessage")
66            .field("type_name", &self.type_name())
67            .field("type_id", &self.tid())
68            .finish()
69    }
70}