// std use std::sync::Arc; // crates use parking_lot::RwLock; use serde::{Deserialize, Serialize}; // internal use crate::runner::BoxedNode; mod ttf; pub struct SimulationState { pub nodes: Arc>>>, } impl SimulationState { #[inline] pub fn new(nodes: Vec>) -> Self { Self { nodes: Arc::new(RwLock::new(nodes)), } } } /// A ward is a computation over the `NetworkState`, it must return true if the state satisfies /// the warding conditions. It is used to stop the consensus simulation if such condition is reached. pub trait SimulationWard { type SimulationState; fn analyze(&mut self, state: &Self::SimulationState) -> bool; } /// Ward dispatcher /// Enum to avoid Boxing (Box) wards. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum Ward { Max(ttf::MaxWard), Sum(ttf::SumWard), } pub enum WardCondition<'a> { Max(&'a ttf::MaxWard), Sum(&'a ttf::SumWardCondition), } impl Ward { pub fn simulation_ward_mut( &mut self, ) -> &mut dyn SimulationWard> { match self { Ward::Max(ward) => ward, Ward::Sum(ward) => ward, } } } impl SimulationWard for Ward { type SimulationState = SimulationState; fn analyze(&mut self, state: &Self::SimulationState) -> bool { self.simulation_ward_mut().analyze(state) } }