#[derive(Debug, Clone)] pub struct KabelRuntimeError { pub kind: RuntimeErrorKind, pub message: String, pub hint: Option, pub line: usize, pub code: String, } impl KabelRuntimeError { pub fn new( kind: RuntimeErrorKind, message: String, hint: Option, line: usize, code: String, ) -> Self { Self { kind, message, hint, line, code, } } } impl std::fmt::Display for KabelRuntimeError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&format!( "Error {:0>4}: {1} at line {2}\n\ {3}\n", self.kind.clone() as usize, self.message, self.line + 1, self.code, ))?; if let Some(ref hint) = self.hint { f.write_str(&format!("\n{0}", hint))?; } Ok(()) } } impl std::error::Error for KabelRuntimeError {} #[derive(Debug, Clone)] pub enum RuntimeErrorKind { MismatchedTypes, WrongType, IncorrectArity, ArrayOutOfBounds, } impl std::fmt::Display for RuntimeErrorKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use RuntimeErrorKind::*; match self { MismatchedTypes => f.write_str("Mismatched types"), WrongType => f.write_str("Wrong type"), IncorrectArity => f.write_str("Incorrect arity"), ArrayOutOfBounds => f.write_str("Array out of bounds"), } } } impl From for usize { fn from(value: RuntimeErrorKind) -> Self { use RuntimeErrorKind::*; match value { MismatchedTypes => 0x00, WrongType => 0x01, IncorrectArity => 0x02, ArrayOutOfBounds => 0x03, } } }