use crate::transducer::InvalidValue; /// An error that it is likely impossible to recover from. This error should only be created in /// situations where attempts to recover have already been attempted and have failed. Error handling /// should consist of attempting to alert another system for maintenance and attempting to shut down /// any systems that depend on the correct functionality of the component having errors. /// /// In many systems there can be a single function for handling any critical error as a critical /// error always means everything needs to be stopped. #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum CriticalError { /// Critical communication failed and retries are either impossible or also failed. Communication, InvalidValue(InvalidValue), } impl CriticalError { //TODO: Switch to using ! as the return type for the FnOnce and the entire function when the ! feature is stabilized pub fn emergency_procedure(self, procedure: impl FnOnce(CriticalError)) { procedure(self); } } /// [Result] where error type is [CriticalError]. pub trait CriticalErrResult: Copy { type Value: Copy; //TODO: Switch to using ! as the return type for the FnOnce when the ! feature is stabilized /// Execute emergency procedure in the event of a critical, the emergency procedure cannot /// return. It should usually terminate the program, potentially rebooting the device in some sort of recovery mode. fn err_emproc(self, procedure: impl FnOnce(CriticalError)) -> Self::Value; } impl CriticalErrResult for Result { type Value = T; //TODO: Switch to using ! as the return type for the FnOnce when the ! feature is stabilized fn err_emproc(self, procedure: impl FnOnce(CriticalError)) -> Self::Value { match self { Ok(val) => val, Err(error) => { error.emergency_procedure(procedure); //TODO: Remove this panic when we switch to ! return type panic!() }, } } }