openmina_core/
invariants.rs

1use std::any::Any;
2
3pub trait InvariantService: redux::Service {
4    type ClusterInvariantsState<'a>: 'a + std::ops::DerefMut<Target = InvariantsState>
5    where
6        Self: 'a;
7
8    fn node_id(&self) -> usize {
9        0
10    }
11
12    fn invariants_state(&mut self) -> &mut InvariantsState;
13
14    fn cluster_invariants_state<'a>(&'a mut self) -> Option<Self::ClusterInvariantsState<'a>>
15    where
16        Self: 'a,
17    {
18        None
19    }
20}
21
22#[derive(Default)]
23pub struct InvariantsState(Vec<Box<dyn 'static + Send + Any>>);
24
25impl InvariantsState {
26    pub fn get<T: 'static + Send + Default>(&mut self, i: usize) -> &mut T {
27        self.0.resize_with(i + 1, || Box::new(()));
28        let v = self.0.get_mut(i).unwrap();
29        if v.is::<T>() {
30            v.downcast_mut().unwrap()
31        } else {
32            *v = Box::<T>::default();
33            v.downcast_mut().unwrap()
34        }
35    }
36
37    pub fn take(&mut self) -> Self {
38        std::mem::take(self)
39    }
40}