use std::{
error::Error,
fmt::{Display, Formatter},
};
mod from_pest;
mod from_serde_json;
mod from_std;
mod from_validate;
#[cfg(feature = "wasm")]
mod from_wasm;
pub type Result<T, E = JssError> = std::result::Result<T, E>;
pub type Errors<'a> = &'a mut Vec<JssError>;
#[derive(Debug)]
pub struct JssError {
pub kind: Box<JssErrorKind>,
pub line: u32,
pub column: u32,
}
#[derive(Debug)]
pub enum JssErrorKind {
IOError(std::io::Error),
FormatError(std::fmt::Error),
SyntaxError(String),
RuntimeError(String),
TypeMismatch(String),
ValidationFail(String),
UndefinedVariable {
name: String,
},
Unreachable,
}
impl JssError {
pub fn undefined_variable<S>(msg: S) -> Self
where
S: Into<String>,
{
let kind = JssErrorKind::UndefinedVariable { name: msg.into() };
Self { kind: Box::new(kind), line: 0, column: 0 }
}
pub fn runtime_error<S>(msg: S) -> Self
where
S: Into<String>,
{
let kind = JssErrorKind::RuntimeError(msg.into());
Self { kind: Box::new(kind), line: 0, column: 0 }
}
pub fn syntax_error<S>(msg: S) -> Self
where
S: Into<String>,
{
let kind = JssErrorKind::SyntaxError(msg.into());
Self { kind: Box::new(kind), line: 0, column: 0 }
}
pub fn unreachable() -> Self {
Self { kind: Box::new(JssErrorKind::Unreachable), line: 0, column: 0 }
}
}
impl Error for JssError {}
impl Display for JssError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:indent$}{}", self.kind, indent = 4)
}
}
impl Display for JssErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::IOError(e) => {
write!(f, "{}", e)
}
Self::FormatError(e) => {
write!(f, "{}", e)
}
Self::SyntaxError(msg) => {
f.write_str("SyntaxError: ")?;
f.write_str(msg)
}
Self::TypeMismatch(msg) => {
f.write_str("TypeError: ")?;
f.write_str(msg)
}
Self::RuntimeError(msg) => {
f.write_str("RuntimeError: ")?;
f.write_str(msg)
}
JssErrorKind::ValidationFail(msg) => {
f.write_str("RuntimeError: ")?;
f.write_str(msg)
}
Self::UndefinedVariable { name } => {
write!(f, "RuntimeError: Variable {} not found in scope", name)
}
Self::Unreachable => {
f.write_str("InternalError: ")?;
f.write_str("Entered unreachable code!")
}
}
}
}