#[derive(Debug, Clone)]
pub struct KabelRuntimeError {
pub kind: RuntimeErrorKind,
pub message: String,
pub hint: Option<String>,
pub line: usize,
pub code: String,
}
impl KabelRuntimeError {
pub fn new(kind: RuntimeErrorKind, message: String, hint: Option<String>, 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<RuntimeErrorKind> for usize {
fn from(value: RuntimeErrorKind) -> Self {
use RuntimeErrorKind::*;
match value {
MismatchedTypes => 0x00,
WrongType => 0x01,
IncorrectArity => 0x02,
ArrayOutOfBounds => 0x03,
}
}
}