1use crate::prelude::*;
2use std::fmt;
3
4#[derive(Debug)]
5pub enum RuntimeError {
6 ArithmeticError(RuntimeErrorStruct),
7 NewAtomicFactError(RuntimeErrorStruct),
8 StoreFactError(RuntimeErrorStruct),
9 ParseError(RuntimeErrorStruct),
10 ExecStmtError(RuntimeErrorStruct),
11 WellDefinedError(RuntimeErrorStruct),
12 VerifyError(RuntimeErrorStruct),
13 UnknownError(RuntimeErrorStruct),
14 InferError(RuntimeErrorStruct),
15 NameAlreadyUsedError(RuntimeErrorStruct),
16 DefineParamsError(RuntimeErrorStruct),
17 InstantiateError(RuntimeErrorStruct),
18}
19
20#[derive(Debug)]
21pub struct RuntimeErrorStruct {
22 pub statement: Option<Stmt>,
23 pub msg: String,
24 pub line_file: LineFile,
25 pub previous_error: Option<Box<RuntimeError>>,
26 pub inside_results: Vec<StmtResult>,
27}
28
29macro_rules! runtime_error_wrapper {
30 ($($wrapper:ident => $variant:ident),* $(,)?) => {
31 $(
32 #[derive(Debug)]
33 pub struct $wrapper(pub RuntimeErrorStruct);
34
35 impl From<$wrapper> for RuntimeError {
36 fn from(w: $wrapper) -> Self {
37 RuntimeError::$variant(w.0)
38 }
39 }
40 )*
41 };
42}
43
44runtime_error_wrapper! {
45 ArithmeticRuntimeError => ArithmeticError,
46 NewAtomicFactRuntimeError => NewAtomicFactError,
47 StoreFactRuntimeError => StoreFactError,
48 ParseRuntimeError => ParseError,
49 WellDefinedRuntimeError => WellDefinedError,
50 VerifyRuntimeError => VerifyError,
51 UnknownRuntimeError => UnknownError,
52 InferRuntimeError => InferError,
53 NameAlreadyUsedRuntimeError => NameAlreadyUsedError,
54 DefineParamsRuntimeError => DefineParamsError,
55 InstantiateRuntimeError => InstantiateError,
56}
57
58impl RuntimeErrorStruct {
59 pub fn new(
60 statement: Option<Stmt>,
61 msg: String,
62 line_file: LineFile,
63 previous_error: Option<RuntimeError>,
64 inside_results: Vec<StmtResult>,
65 ) -> Self {
66 RuntimeErrorStruct {
67 statement,
68 msg,
69 line_file,
70 previous_error: previous_error.map(Box::new),
71 inside_results,
72 }
73 }
74}
75
76pub fn short_exec_error(
77 stmt: Stmt,
78 message: impl Into<String>,
79 cause: Option<RuntimeError>,
80 inside_results: Vec<StmtResult>,
81) -> RuntimeError {
82 let message = message.into();
83 let line_file = stmt.line_file();
84 RuntimeError::ExecStmtError(RuntimeErrorStruct::new(
85 Some(stmt.clone()),
86 message,
87 line_file.clone(),
88 cause,
89 inside_results,
90 ))
91}
92
93impl std::error::Error for RuntimeError {}
94
95impl RuntimeError {
96 pub fn wrap_new_atomic_fact_as_store_conflict(e: RuntimeError) -> RuntimeError {
97 match e {
98 RuntimeError::NewAtomicFactError(s) => {
99 NewAtomicFactRuntimeError(RuntimeErrorStruct::new(
100 s.statement.clone(),
101 s.msg.clone(),
102 s.line_file.clone(),
103 Some(NewAtomicFactRuntimeError(s).into()),
104 vec![],
105 ))
106 .into()
107 }
108 _ => e,
109 }
110 }
111
112 pub fn line_file(&self) -> LineFile {
113 match self {
114 RuntimeError::ArithmeticError(e) => e.line_file.clone(),
115 RuntimeError::NewAtomicFactError(e) => e.line_file.clone(),
116 RuntimeError::StoreFactError(e) => e.line_file.clone(),
117 RuntimeError::ParseError(e) => e.line_file.clone(),
118 RuntimeError::ExecStmtError(e) => e.line_file.clone(),
119 RuntimeError::WellDefinedError(e) => e.line_file.clone(),
120 RuntimeError::VerifyError(e) => e.line_file.clone(),
121 RuntimeError::UnknownError(e) => e.line_file.clone(),
122 RuntimeError::InferError(e) => e.line_file.clone(),
123 RuntimeError::NameAlreadyUsedError(e) => e.line_file.clone(),
124 RuntimeError::DefineParamsError(e) => e.line_file.clone(),
125 RuntimeError::InstantiateError(e) => e.line_file.clone(),
126 }
127 }
128
129 pub fn display_label(&self) -> &'static str {
130 match self {
131 RuntimeError::ArithmeticError(_) => "ArithmeticError",
132 RuntimeError::NewAtomicFactError(_) => "NewAtomicFactError",
133 RuntimeError::StoreFactError(_) => "StoreFactError",
134 RuntimeError::ParseError(_) => "ParseError",
135 RuntimeError::ExecStmtError(_) => "ExecStmtError",
136 RuntimeError::WellDefinedError(_) => "WellDefinedError",
137 RuntimeError::VerifyError(_) => "VerifyError",
138 RuntimeError::UnknownError(_) => "UnknownError",
139 RuntimeError::InferError(_) => "InferError",
140 RuntimeError::NameAlreadyUsedError(_) => "NameAlreadyUsedError",
141 RuntimeError::DefineParamsError(_) => "DefineParamsError",
142 RuntimeError::InstantiateError(_) => "InstantiateError",
143 }
144 }
145}
146
147impl fmt::Display for RuntimeError {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 write!(f, "{}", "error")
151 }
152}
153
154impl fmt::Display for RuntimeErrorStruct {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
156 write!(f, "{}", self.msg)
157 }
158}
159
160impl std::error::Error for RuntimeErrorStruct {}
161
162impl RuntimeErrorStruct {
163 pub fn new_with_just_msg(msg: String) -> Self {
164 Self::new(None, msg, default_line_file(), None, vec![])
165 }
166
167 pub fn new_with_msg_and_line_file(msg: String, line_file: LineFile) -> Self {
168 Self::new(None, msg, line_file, None, vec![])
169 }
170
171 pub fn new_with_msg_and_cause(msg: String, cause: RuntimeError) -> Self {
172 Self::new(None, msg, default_line_file(), Some(cause), vec![])
173 }
174}