use scru128::Scru128Id;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Slots {
confirmed: Option<Scru128Id>,
pending: Option<Scru128Id>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event {
Create { id: Scru128Id },
Active { source: Scru128Id },
Invalid { source: Scru128Id },
Term,
Fin,
Replaced,
Stopped,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ThresholdPick {
None,
Start {
id: Scru128Id,
fallback: Option<Scru128Id>,
},
}
impl Slots {
pub fn new() -> Self {
Self::default()
}
pub fn apply(&mut self, event: Event) {
match event {
Event::Create { id } => {
self.pending = Some(id);
}
Event::Active { source } => {
self.confirmed = Some(source);
if self.pending == Some(source) {
self.pending = None;
}
}
Event::Invalid { source } => {
if self.pending == Some(source) {
self.pending = None;
}
}
Event::Term | Event::Fin => {
self.confirmed = None;
self.pending = None;
}
Event::Replaced | Event::Stopped => {}
}
}
pub fn replay<I: IntoIterator<Item = Event>>(events: I) -> Self {
let mut s = Self::new();
for e in events {
s.apply(e);
}
s
}
pub fn threshold(&self) -> ThresholdPick {
match (self.pending, self.confirmed) {
(Some(p), c) => ThresholdPick::Start { id: p, fallback: c },
(None, Some(c)) => ThresholdPick::Start {
id: c,
fallback: None,
},
(None, None) => ThresholdPick::None,
}
}
pub fn confirmed(&self) -> Option<Scru128Id> {
self.confirmed
}
pub fn pending(&self) -> Option<Scru128Id> {
self.pending
}
}