1use std::{
2 error::Error,
3 fmt::{Display, Formatter},
4};
5
6mod from_pest;
7mod from_serde_json;
8mod from_std;
9mod from_validate;
10#[cfg(feature = "wasm")]
11mod from_wasm;
12
13pub type Result<T, E = JssError> = std::result::Result<T, E>;
15pub type Errors<'a> = &'a mut Vec<JssError>;
17
18#[derive(Debug)]
20pub struct JssError {
21 pub kind: Box<JssErrorKind>,
23 pub line: u32,
24 pub column: u32,
25}
26
27#[derive(Debug)]
29pub enum JssErrorKind {
30 IOError(std::io::Error),
32 FormatError(std::fmt::Error),
35 SyntaxError(String),
37 RuntimeError(String),
39 TypeMismatch(String),
41 ValidationFail(String),
43 UndefinedVariable {
45 name: String,
47 },
48 Unreachable,
50 }
53
54impl JssError {
55 pub fn undefined_variable<S>(msg: S) -> Self
56 where
57 S: Into<String>,
58 {
59 let kind = JssErrorKind::UndefinedVariable { name: msg.into() };
60 Self { kind: Box::new(kind), line: 0, column: 0 }
61 }
62 pub fn runtime_error<S>(msg: S) -> Self
63 where
64 S: Into<String>,
65 {
66 let kind = JssErrorKind::RuntimeError(msg.into());
67 Self { kind: Box::new(kind), line: 0, column: 0 }
68 }
69 pub fn syntax_error<S>(msg: S) -> Self
70 where
71 S: Into<String>,
72 {
73 let kind = JssErrorKind::SyntaxError(msg.into());
74 Self { kind: Box::new(kind), line: 0, column: 0 }
75 }
76
77 pub fn unreachable() -> Self {
78 Self { kind: Box::new(JssErrorKind::Unreachable), line: 0, column: 0 }
79 }
80}
81
82impl Error for JssError {}
83
84impl Display for JssError {
85 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
86 write!(f, "{:indent$}{}", self.kind, indent = 4)
87 }
88}
89
90impl Display for JssErrorKind {
91 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
92 match self {
93 Self::IOError(e) => {
94 write!(f, "{}", e)
95 }
96 Self::FormatError(e) => {
97 write!(f, "{}", e)
98 }
99 Self::SyntaxError(msg) => {
100 f.write_str("SyntaxError: ")?;
101 f.write_str(msg)
102 }
103 Self::TypeMismatch(msg) => {
104 f.write_str("TypeError: ")?;
105 f.write_str(msg)
106 }
107 Self::RuntimeError(msg) => {
108 f.write_str("RuntimeError: ")?;
109 f.write_str(msg)
110 }
111 JssErrorKind::ValidationFail(msg) => {
112 f.write_str("RuntimeError: ")?;
113 f.write_str(msg)
114 }
115 Self::UndefinedVariable { name } => {
116 write!(f, "RuntimeError: Variable {} not found in scope", name)
117 }
118 Self::Unreachable => {
119 f.write_str("InternalError: ")?;
120 f.write_str("Entered unreachable code!")
121 }
122 }
123 }
124}