1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use std::any::{Any, TypeId};
#[derive(Debug)]
pub enum MessageError {
WrongType(TypeId),
}
#[derive(Debug)]
pub struct MessageBox {
message: Box<dyn Any>,
message_type: TypeId,
}
impl MessageBox {
pub fn new<M: Any>(message: M) -> Self {
MessageBox {
message: Box::new(message),
message_type: TypeId::of::<M>(),
}
}
pub fn is_type<M: Any>(&self) -> bool {
self.message_type == TypeId::of::<M>()
}
pub fn message_type(&self) -> TypeId {
self.message_type
}
pub fn downcast<M: Any>(self) -> Result<M, MessageError> {
if self.message_type == TypeId::of::<M>() {
return Ok(*self.message.downcast::<M>().unwrap());
}
Err(MessageError::WrongType(TypeId::of::<M>()))
}
pub fn downcast_ref<M: Any>(&self) -> Result<&M, MessageError> {
if self.message_type == TypeId::of::<M>() {
return Ok(&*self.message.downcast_ref::<M>().unwrap());
}
Err(MessageError::WrongType(TypeId::of::<M>()))
}
}
#[derive(Default, Clone)]
pub struct StringMessage(pub String);
impl From<&str> for StringMessage {
fn from(s: &str) -> Self {
StringMessage(s.to_string())
}
}
impl From<String> for StringMessage {
fn from(s: String) -> Self {
StringMessage(s)
}
}
impl Into<MessageBox> for StringMessage {
fn into(self) -> MessageBox {
MessageBox::new(self)
}
}