wolfram_error/errors/
mod.rs1use diagnostic::{Diagnostic, FileID, FileSpan, ReportKind};
2use std::{
3 error::Error,
4 fmt::{Debug, Display, Formatter},
5 ops::Range,
6};
7
8pub type Result<T = ()> = std::result::Result<T, WolframError>;
9
10pub type Validation<T> = validatus::Validation<T, WolframError>;
11
12pub struct WolframError {
13 kind: Box<WolframErrorKind>,
14}
15
16impl WolframError {
17 pub fn kind(&self) -> &WolframErrorKind {
19 &*self.kind
20 }
21
22 pub fn as_report(&self) -> Diagnostic {
23 match self.kind() {
24 WolframErrorKind::RuntimeError { message } => Diagnostic::new(ReportKind::Error).with_message(message).finish(),
25 WolframErrorKind::SyntaxError { message, location } => Diagnostic::new(ReportKind::Error)
26 .with_message(message)
27 .with_location(location.get_file(), Some(location.get_start()))
28 .finish(),
29 }
30 }
31}
32
33#[derive(Debug)]
34pub enum WolframErrorKind {
35 RuntimeError { message: String },
36 SyntaxError { message: String, location: FileSpan },
37}
38impl Error for WolframError {}
39
40impl Error for WolframErrorKind {}
41impl Debug for WolframError {
42 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
43 Debug::fmt(&self.kind, f)
44 }
45}
46
47impl Display for WolframError {
48 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49 Display::fmt(&self.kind, f)
50 }
51}
52impl Display for WolframErrorKind {
53 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54 match self {
55 WolframErrorKind::RuntimeError { message } => {
56 f.write_str("Runtime Error: ")?;
57 f.write_str(message)
58 }
59 WolframErrorKind::SyntaxError { message, location } => {
60 f.write_str("Syntax Error: ")?;
61 f.write_str(message)?;
62 f.write_str(" at ")?;
63 Debug::fmt(location, f)
64 }
65 }
66 }
67}
68
69impl From<WolframErrorKind> for WolframError {
70 fn from(value: WolframErrorKind) -> Self {
71 WolframError { kind: Box::new(value) }
72 }
73}
74
75impl WolframError {
76 pub fn runtime_error<S>(message: S) -> Self
78 where
79 S: ToString,
80 {
81 Self { kind: Box::new(WolframErrorKind::RuntimeError { message: message.to_string() }) }
82 }
83 pub fn syntax_error<S>(message: S) -> Self
85 where
86 S: ToString,
87 {
88 Self { kind: Box::new(WolframErrorKind::SyntaxError { message: message.to_string(), location: Default::default() }) }
89 }
90 pub fn set_file(&mut self, file: FileID) {
92 self.kind.set_file(file)
93 }
94 pub fn with_file(mut self, file: FileID) -> Self {
96 self.set_file(file);
97 self
98 }
99 pub fn set_span(&mut self, range: Range<usize>) {
101 self.kind.set_span(range)
102 }
103 pub fn with_span(mut self, range: Range<usize>) -> Self {
105 self.set_span(range);
106 self
107 }
108 pub fn set_file_span(&mut self, span: FileSpan) {
110 self.kind.set_file_span(span)
111 }
112 pub fn with_file_span(mut self, span: FileSpan) -> Self {
114 self.set_file_span(span);
115 self
116 }
117}
118
119impl WolframErrorKind {
120 pub fn set_file(&mut self, file: FileID) {
123 match self {
124 Self::RuntimeError { .. } => {}
125 Self::SyntaxError { location: span, .. } => span.set_file(file),
126 }
127 }
128 pub fn set_span(&mut self, range: Range<usize>) {
131 match self {
132 Self::RuntimeError { .. } => {}
133 Self::SyntaxError { location: span, .. } => span.set_range(range),
134 }
135 }
136 pub fn set_file_span(&mut self, span: FileSpan) {
138 match self {
139 Self::RuntimeError { .. } => {}
140 Self::SyntaxError { location, .. } => *location = span,
141 }
142 }
143}