use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum Freio {
#[default]
Released,
Engaged { at_unix: u64 },
}
impl Freio {
#[must_use]
pub const fn is_engaged(self) -> bool {
matches!(self, Self::Engaged { .. })
}
#[must_use]
pub const fn engaged_at(self) -> Option<u64> {
match self {
Self::Engaged { at_unix } => Some(at_unix),
Self::Released => None,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Admission {
Accept,
Refuse(RefusalReason),
OnlyLeader { id: u64 },
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum RefusalReason {
Policy,
Freio,
}
impl RefusalReason {
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Policy => "policy",
Self::Freio => "freio",
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn released_is_the_default_so_landing_freio_changes_nothing() {
assert_eq!(Freio::default(), Freio::Released);
assert!(!Freio::default().is_engaged());
assert_eq!(Freio::default().engaged_at(), None);
}
#[test]
fn an_engaged_brake_remembers_when() {
let f = Freio::Engaged { at_unix: 1_785_000_000 };
assert!(f.is_engaged());
assert_eq!(f.engaged_at(), Some(1_785_000_000));
}
#[test]
fn a_freio_refusal_is_not_a_policy_refusal() {
assert_ne!(
Admission::Refuse(RefusalReason::Freio),
Admission::Refuse(RefusalReason::Policy)
);
assert_eq!(RefusalReason::Freio.label(), "freio");
}
#[test]
fn the_engaged_variant_is_daemon_minted_only() {
let json = r#"{"kind":"engaged","at_unix":1}"#;
let f: Freio = serde_json::from_str(json).expect("Freio is decodable");
assert_eq!(f.engaged_at(), Some(1));
}
}