#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum FaultSeverity {
Info,
Warning,
Error,
Critical,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FaultResponse {
LogAndContinue,
Degrade,
EmergencyStop,
}
impl FaultSeverity {
pub fn default_response(self) -> FaultResponse {
match self {
FaultSeverity::Info | FaultSeverity::Warning => FaultResponse::LogAndContinue,
FaultSeverity::Error => FaultResponse::Degrade,
FaultSeverity::Critical => FaultResponse::EmergencyStop,
}
}
}
#[derive(Debug, Clone)]
pub struct FaultDef {
pub id: u16,
pub name: &'static str,
pub severity: FaultSeverity,
pub response: FaultResponse,
}
#[derive(Debug, Clone, Copy)]
pub struct FaultEvent {
pub fault_id: u16,
pub severity: FaultSeverity,
pub response: FaultResponse,
pub timestamp: f64,
}
impl FaultEvent {
pub fn new(def: &FaultDef, timestamp: f64) -> Self {
Self {
fault_id: def.id,
severity: def.severity,
response: def.response,
timestamp,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn severity_ordering() {
assert!(FaultSeverity::Info < FaultSeverity::Warning);
assert!(FaultSeverity::Warning < FaultSeverity::Error);
assert!(FaultSeverity::Error < FaultSeverity::Critical);
}
#[test]
fn default_responses() {
assert_eq!(
FaultSeverity::Info.default_response(),
FaultResponse::LogAndContinue
);
assert_eq!(
FaultSeverity::Warning.default_response(),
FaultResponse::LogAndContinue
);
assert_eq!(
FaultSeverity::Error.default_response(),
FaultResponse::Degrade
);
assert_eq!(
FaultSeverity::Critical.default_response(),
FaultResponse::EmergencyStop
);
}
#[test]
fn fault_event_from_def() {
let def = FaultDef {
id: 42,
name: "overtemp",
severity: FaultSeverity::Critical,
response: FaultResponse::EmergencyStop,
};
let event = FaultEvent::new(&def, 1.5);
assert_eq!(event.fault_id, 42);
assert_eq!(event.severity, FaultSeverity::Critical);
assert_eq!(event.response, FaultResponse::EmergencyStop);
assert_eq!(event.timestamp, 1.5);
}
}