#[derive(Debug, Clone)] pub struct KabelError { pub kind: ErrorKind, pub message: String, pub hint: Option, pub line: usize, pub column: usize, pub code: String, } impl KabelError { pub fn new(kind: ErrorKind, message: String, hint: Option, line: usize, column: usize, code: String) -> Self { Self { kind, message, hint, line, column, code, } } } impl std::fmt::Display for KabelError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let caret_space: String = vec![' '; self.column].iter().collect(); f.write_str(&format!( "Error {:0>4}: {1} at line {2}, column {3}\n\ {4}\n\ {5}^", self.kind.clone() as usize, self.message, self.line + 1, self.column + 1, self.code, caret_space ))?; if let Some(ref hint) = self.hint { f.write_str(&format!("\n{0}{1}", caret_space, hint))?; } Ok(()) } } impl std::error::Error for KabelError {} #[derive(Debug, Clone, PartialEq, Eq)] pub enum ErrorKind { UnexpectedEof, UnexpectedCharacter, UnexpectedToken, MissingDelimiter, OutOfScope, VariableAlreadyDeclaredVariable, VariableAlreadyDeclaredFunction, FunctionAlreadyDeclaredVariable, FunctionAlreadyDeclaredFunction, IncorrectArity, } impl std::fmt::Display for ErrorKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use ErrorKind::*; match self { UnexpectedEof => f.write_str("Unexpected End of File"), UnexpectedCharacter => f.write_str("Unrecognized Charcter"), UnexpectedToken => f.write_str("Unrecognized Token"), MissingDelimiter => f.write_str("Missing delimiter"), OutOfScope => f.write_str("Out of scope"), VariableAlreadyDeclaredVariable => f.write_str("Variable already declared variable"), VariableAlreadyDeclaredFunction => f.write_str("Variable already declared function"), FunctionAlreadyDeclaredVariable => f.write_str("Function already declared variable"), FunctionAlreadyDeclaredFunction => f.write_str("Function already declared function"), IncorrectArity => f.write_str("Incorrect arity"), } } } impl From for usize { fn from(value: ErrorKind) -> Self { use ErrorKind::*; match value { UnexpectedEof => 0x00, UnexpectedCharacter => 0x01, UnexpectedToken => 0x02, MissingDelimiter => 0x03, OutOfScope => 0x04, VariableAlreadyDeclaredVariable => 0x05, VariableAlreadyDeclaredFunction => 0x06, FunctionAlreadyDeclaredVariable => 0x07, FunctionAlreadyDeclaredFunction => 0x08, IncorrectArity => 0x09, } } }