use std::any::Any;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Stage {
Validate,
Process,
Post,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BusKind {
Instant,
Game,
}
pub trait EventRouting {
const BUS: BusKind;
}
pub trait Event: Any + Send {
fn is_cancelled(&self) -> bool;
fn cancel(&mut self);
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn bus_kind(&self) -> BusKind;
}
#[cfg(test)]
mod tests {
use super::*;
struct TestEvent {
value: i32,
cancelled: bool,
}
impl Event for TestEvent {
fn is_cancelled(&self) -> bool {
self.cancelled
}
fn cancel(&mut self) {
self.cancelled = true;
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn bus_kind(&self) -> BusKind {
BusKind::Instant
}
}
#[test]
fn event_cancellation() {
let mut event = TestEvent {
value: 42,
cancelled: false,
};
assert!(!event.is_cancelled());
event.cancel();
assert!(event.is_cancelled());
assert_eq!(event.value, 42);
}
#[test]
fn event_downcast() {
let mut event = TestEvent {
value: 99,
cancelled: false,
};
let any = event.as_any_mut();
let concrete = any.downcast_mut::<TestEvent>().unwrap();
concrete.value = 100;
assert_eq!(event.value, 100);
}
#[test]
fn stage_ordering() {
assert!(Stage::Validate < Stage::Process);
assert!(Stage::Process < Stage::Post);
}
#[test]
fn bus_kind_equality() {
assert_eq!(BusKind::Instant, BusKind::Instant);
assert_eq!(BusKind::Game, BusKind::Game);
assert_ne!(BusKind::Instant, BusKind::Game);
}
}