refault 0.3.0

deterministic simulation framework for distributed systems using async
Documentation
use std::{any::Any, sync::Arc, time::Duration};

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Event {
    TaskRun(crate::id::Id),
    TimeAdvanced(Duration),
    NodeSpawned(crate::node_id::NodeId),
    TaskSpawned,
}

pub(crate) trait EventHandler: Send {
    fn handle_event(&mut self, event: Event);
    fn finalize(self: Box<Self>) -> Box<dyn Any + Send>;
}

pub(crate) struct NoopEventHandler;

impl EventHandler for NoopEventHandler {
    fn handle_event(&mut self, _: Event) {}

    fn finalize(self: Box<Self>) -> Box<dyn Any + Send> {
        Box::new(())
    }
}

#[derive(Clone)]
pub(crate) struct RecordingEventHandler {
    pub(crate) recorded_events: Vec<Event>,
}

impl RecordingEventHandler {
    pub(crate) fn new() -> Self {
        Self {
            recorded_events: Default::default(),
        }
    }
}

impl EventHandler for RecordingEventHandler {
    fn handle_event(&mut self, event: Event) {
        self.recorded_events.push(event);
    }

    fn finalize(self: Box<Self>) -> Box<dyn Any + Send> {
        Box::new(self.recorded_events)
    }
}

pub(crate) struct ValidatingEventHandler {
    events_to_validate: Arc<Vec<Event>>,
    pub(crate) next_event_index: usize,
}

impl ValidatingEventHandler {
    pub(crate) fn new(previous_events: Arc<Vec<Event>>) -> Self {
        Self {
            events_to_validate: previous_events,
            next_event_index: 0,
        }
    }
}

impl EventHandler for ValidatingEventHandler {
    fn handle_event(&mut self, event: Event) {
        let current_event = event;
        if self.next_event_index >= self.events_to_validate.len() {
            panic!(
                "Non-Determinism detected: Expected no further events, but got '{current_event:?}'",
            );
        }
        let expected = &self.events_to_validate[self.next_event_index];
        if current_event != *expected {
            panic!(
                "Non-Determinism detected: Validation failed for event {index}: Expected '{expected:?}', but got '{current_event:?}'",
                index = self.next_event_index
            );
        }
        self.next_event_index += 1;
    }

    fn finalize(self: Box<Self>) -> Box<dyn Any + Send> {
        let index = self.next_event_index;
        let len = self.events_to_validate.len();
        if index != len {
            panic!("Non-Determinism detected: Expected {len} events but only got {index}",);
        }
        Box::new(())
    }
}