use crate::core::instruction::Instruction; use std::fmt; #[derive(Debug, Clone, Copy)] pub enum Severity { Warning, Error, Fatal, } impl fmt::Display for Severity { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let sev = match self { Self::Warning => "Warning", Self::Error => "Error", Self::Fatal => "Fatal", }; write!(f, "{sev}") } } #[derive(Debug, Clone, Copy)] pub enum AccessType { U8(Option), U16(Option), U32(Option), U64(Option), } impl fmt::Display for AccessType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { &Self::U8(val) => { if let Some(val) = val { write!(f, "write8 with value {val:02X}") } else { write!(f, "read8") } } &Self::U16(val) => { if let Some(val) = val { write!(f, "write16 with value {val:04X}") } else { write!(f, "read16") } } &Self::U32(val) => { if let Some(val) = val { write!(f, "write32 with value {val:08X}") } else { write!(f, "read32") } } &Self::U64(val) => { if let Some(val) = val { write!(f, "write64 with value {val:08X}") } else { write!(f, "read64") } } } } } #[derive(Debug, Clone, Copy)] pub enum Type { UnhandledInstruction(Instruction), UnhandledMemoryAccess(u32, AccessType), } impl fmt::Display for Type { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let err_type = match self { Type::UnhandledInstruction(instr) => { format!("Unhandled instruction: {:02X}", instr.opcode()) } Type::UnhandledMemoryAccess(addr, access) => { format!("Unhandled addr @ {addr:08X} for {access}") } }; write!(f, "{err_type}") } } type Result = std::result::Result; #[derive(Debug, Clone, Copy)] pub struct Error { pub severity: Severity, pub err_type: Type, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[{}]: {}", self.severity, self.err_type) } }