use std::any::Any;
use std::fmt::{Debug, Display, Formatter};
use std::sync::Arc;
use crate::actor::message::message::Message;
use crate::util::element::Element;
use crate::util::queue::priority_queue::PriorityMessage;
#[derive(Debug, Clone)]
pub struct MessageHandle(Arc<dyn Message>);
impl MessageHandle {
pub fn new_arc(msg: Arc<dyn Message>) -> Self {
if msg.as_any().downcast_ref::<MessageHandle>().is_some() {
panic!("MessageHandle can't be used as a message, {:?}", msg);
}
MessageHandle(msg)
}
pub fn new(msg: impl Message + Send + Sync + 'static) -> Self {
MessageHandle(Arc::new(msg))
}
pub fn to_typed<T: Clone + 'static>(&self) -> Option<T> {
if let Some(msg) = self.0.as_any().downcast_ref::<T>() {
Some(msg.clone())
} else {
None
}
}
pub fn as_typed<T: 'static>(&self) -> Option<&T> {
self.0.as_any().downcast_ref::<T>()
}
pub fn is_typed<T: 'static>(&self) -> bool {
self.0.as_any().is::<T>()
}
}
impl Element for MessageHandle {}
impl PriorityMessage for MessageHandle {
fn get_priority(&self) -> Option<i8> {
Some(self.0.get_priority())
}
}
impl Message for MessageHandle {
fn eq_message(&self, other: &dyn Message) -> bool {
self.0.eq_message(other)
}
fn as_any(&self) -> &(dyn Any + Send + Sync + 'static) {
self.0.as_any()
}
}
impl PartialEq for MessageHandle {
fn eq(&self, other: &Self) -> bool {
self.0.eq_message(&*other.0)
}
}
impl Eq for MessageHandle {}
impl std::hash::Hash for MessageHandle {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
(self.0.as_ref() as *const dyn Message).hash(state);
}
}
impl Display for MessageHandle {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_string())
}
}