use std::any::{Any, TypeId};
use std::fmt::Debug;
use std::sync::Arc;
pub mod envelope;
pub mod metadata;
pub use envelope::EventEnvelope;
pub use metadata::EventMetadata;
pub trait Event:
serde::Serialize + serde::de::DeserializeOwned + Send + Sync + Clone + Debug + 'static
{
fn event_type() -> &'static str
where
Self: Sized;
fn type_id() -> TypeId
where
Self: Sized,
{
TypeId::of::<Self>()
}
fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
self
}
}
pub trait JsonSerializableEvent: Event {
fn to_json(&self) -> crate::Result<String> {
serde_json::to_string(self).map_err(|e| crate::Error::SerializationError(e.to_string()))
}
fn from_json(json: &str) -> crate::Result<Self>
where
Self: Sized,
{
serde_json::from_str(json).map_err(|e| crate::Error::SerializationError(e.to_string()))
}
}
impl<T: Event> JsonSerializableEvent for T {}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Default,
serde::Serialize,
serde::Deserialize,
)]
pub enum EventPriority {
Low = 0,
#[default]
Normal = 1,
High = 2,
Critical = 3,
}
pub trait HasPriority {
fn priority(&self) -> EventPriority {
EventPriority::default()
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BroadcastEvent {
pub message: String,
}
impl Event for BroadcastEvent {
fn event_type() -> &'static str {
"BroadcastEvent"
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::event;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
struct TestEvent {
id: u64,
data: String,
}
impl Event for TestEvent {
fn event_type() -> &'static str {
"TestEvent"
}
}
#[test]
fn test_event_type_id() {
let type_id1 = <event::tests::TestEvent as event::Event>::type_id();
let type_id2 = <event::tests::TestEvent as event::Event>::type_id();
assert_eq!(type_id1, type_id2);
}
#[test]
fn test_event_as_any() {
let event = Arc::new(TestEvent {
id: 123,
data: "test".to_string(),
});
let any = event.clone().as_any();
let downcast = any.downcast_ref::<TestEvent>();
assert!(downcast.is_some());
assert_eq!(downcast.unwrap().id, 123);
assert_eq!(downcast.unwrap().data, "test");
}
#[test]
fn test_priority_ordering() {
assert!(EventPriority::Critical > EventPriority::High);
assert!(EventPriority::High > EventPriority::Normal);
assert!(EventPriority::Normal > EventPriority::Low);
}
}