1use super::K;
8use crate::qtype;
9use std::error::Error as StdError;
10use std::fmt;
11use std::io::Error as IOError;
12
13pub enum Error {
19 InvalidDateTime,
21 IO(IOError),
23 InvalidCast {
25 from: &'static str,
26 to: &'static str,
27 },
28 InvalidCastList(&'static str),
30 IndexOutOfBounds { length: usize, index: usize },
32 InvalidOperation {
34 operator: &'static str,
35 operand_type: &'static str,
36 expected: Option<&'static str>,
37 },
38 LengthMismatch {
40 key_length: usize,
41 value_length: usize,
42 },
43 NoSuchColumn(String),
45 InsertWrongElement {
47 is_insert: bool,
48 destination: &'static str,
49 expected: &'static str,
50 },
51 PopFromEmptyList,
53 Object(K),
55}
56
57impl Error {
62 pub(crate) fn invalid_cast(from: i8, to: i8) -> Self {
64 Self::InvalidCast {
65 from: type_to_string(from),
66 to: type_to_string(to),
67 }
68 }
69
70 pub(crate) fn invalid_cast_list(from: i8) -> Self {
72 Self::InvalidCastList(type_to_string(from))
73 }
74
75 pub(crate) fn index_out_of_bounds(length: usize, index: usize) -> Self {
77 Self::IndexOutOfBounds { length, index }
78 }
79
80 pub(crate) fn invalid_operation(
82 operator: &'static str,
83 operand_type: i8,
84 expected: Option<i8>,
85 ) -> Self {
86 Self::InvalidOperation {
87 operator,
88 operand_type: type_to_string(operand_type),
89 expected: expected.map(type_to_string),
90 }
91 }
92
93 pub(crate) fn length_mismatch(key_length: usize, value_length: usize) -> Self {
95 Self::LengthMismatch {
96 key_length,
97 value_length,
98 }
99 }
100
101 pub(crate) fn no_such_column(column: String) -> Self {
103 Self::NoSuchColumn(column)
104 }
105
106 pub(crate) fn insert_wrong_element(
108 is_insert: bool,
109 destination: i8,
110 expected: &'static str,
111 ) -> Self {
112 Self::InsertWrongElement {
113 is_insert,
114 destination: type_to_string(destination),
115 expected,
116 }
117 }
118
119 pub(crate) fn pop_from_empty_list() -> Self {
121 Self::PopFromEmptyList
122 }
123
124 pub(crate) fn object(returned: K) -> Self {
126 Self::Object(returned)
127 }
128
129 pub fn into_inner(self) -> Option<K> {
144 match self {
145 Self::Object(object) => Some(object),
146 _ => None,
147 }
148 }
149}
150
151impl From<IOError> for Error {
152 fn from(error: IOError) -> Self {
153 Self::IO(error)
154 }
155}
156
157impl PartialEq<Self> for Error {
158 fn eq(&self, other: &Error) -> bool {
159 match (self, other) {
160 (Self::IO(left), Self::IO(right)) => left.to_string() == right.to_string(),
161 (Self::IO(_), _) => false,
162 (Self::InvalidCast { from: f, to: t }, Self::InvalidCast { from: f2, to: t2 }) => {
163 f == f2 && t == t2
164 }
165 (Self::InvalidCastList(left), Self::InvalidCastList(right)) => left == right,
166 (
167 Self::IndexOutOfBounds {
168 length: l,
169 index: i,
170 },
171 Self::IndexOutOfBounds {
172 length: l2,
173 index: i2,
174 },
175 ) => l == l2 && i == i2,
176 (
177 Self::InvalidOperation {
178 operator: o,
179 operand_type: ot,
180 expected: e,
181 },
182 Self::InvalidOperation {
183 operator: o2,
184 operand_type: ot2,
185 expected: e2,
186 },
187 ) => o == o2 && ot == ot2 && e == e2,
188 (
189 Self::LengthMismatch {
190 key_length: k,
191 value_length: l,
192 },
193 Self::LengthMismatch {
194 key_length: k2,
195 value_length: l2,
196 },
197 ) => k == k2 && l == l2,
198 (Self::NoSuchColumn(left), Self::NoSuchColumn(right)) => left == right,
199 (
200 Self::InsertWrongElement {
201 is_insert: i,
202 destination: d,
203 expected: e,
204 },
205 Self::InsertWrongElement {
206 is_insert: i2,
207 destination: d2,
208 expected: e2,
209 },
210 ) => i == i2 && d == d2 && e == e2,
211 (Self::Object(left), Self::Object(right)) => {
212 left.0.qtype == right.0.qtype && left.0.attribute == right.0.attribute
213 }
214 (Self::PopFromEmptyList, Self::PopFromEmptyList) => true,
215 _ => false,
216 }
217 }
218}
219
220impl fmt::Display for Error {
221 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
222 match self {
223 Self::InvalidDateTime => write!(f, "invalid datetime"),
224 Self::IO(error) => write!(f, "IO error: {}", error),
225 Self::InvalidCast { from, to } => write!(f, "invalid cast from {} to {}", from, to),
226 Self::InvalidCastList(from) => {
227 write!(f, "invalid cast from {} to list of generics T", from)
228 }
229 Self::IndexOutOfBounds { length, index } => write!(
230 f,
231 "index out of bounds: specified {} but length is {}",
232 index, length
233 ),
234 Self::InvalidOperation {
235 operator,
236 operand_type,
237 expected,
238 } => match expected {
239 Some(expected_type) => write!(
240 f,
241 "invalid operation {} on {}. expected: {}",
242 operator, operand_type, expected_type
243 ),
244 None => write!(f, "invalid operation {} on {}", operator, operand_type),
245 },
246 Self::LengthMismatch {
247 key_length,
248 value_length,
249 } => write!(
250 f,
251 "key-value length mismatch: {} and {}",
252 key_length, value_length
253 ),
254 Self::NoSuchColumn(column) => write!(f, "no such column: {}", column),
255 Self::InsertWrongElement {
256 is_insert,
257 destination,
258 expected,
259 } => {
260 let operation = match is_insert {
261 true => "insert",
262 false => "push",
263 };
264 write!(
265 f,
266 "{} wrong element to {}: expected {}",
267 operation, destination, expected
268 )
269 }
270 Self::Object(object) => write!(f, "{}", object),
271 Self::PopFromEmptyList => write!(f, "pop from empty list"),
272 }
273 }
274}
275
276impl fmt::Debug for Error {
277 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
278 match self {
279 Self::InvalidDateTime => write!(f, "invalid datetime"),
280 Self::IO(error) => write!(f, "IO error: {:?}", error),
281 Self::InvalidCast { from, to } => write!(f, "invalid cast from {} to {}", from, to),
282 Self::InvalidCastList(from) => {
283 write!(f, "invalid cast from {} to list of generics T", from)
284 }
285 Self::IndexOutOfBounds { length, index } => write!(
286 f,
287 "index out of bounds: specified {} but length is {}",
288 index, length
289 ),
290 Self::InvalidOperation {
291 operator,
292 operand_type,
293 expected,
294 } => match expected {
295 Some(expected_type) => write!(
296 f,
297 "invalid operation {} on {}. expected: {}",
298 operator, operand_type, expected_type
299 ),
300 None => write!(f, "invalid operation {} on {}", operator, operand_type),
301 },
302 Self::LengthMismatch {
303 key_length,
304 value_length,
305 } => write!(
306 f,
307 "key-value length mismatch: {} and {}",
308 key_length, value_length
309 ),
310 Self::NoSuchColumn(column) => write!(f, "no such column: {}", column),
311 Self::InsertWrongElement {
312 is_insert,
313 destination,
314 expected,
315 } => {
316 let operation = match is_insert {
317 true => "insert",
318 false => "push",
319 };
320 write!(
321 f,
322 "{} wrong element to {}: expected {}",
323 operation, destination, expected
324 )
325 }
326 Self::Object(object) => write!(f, "{}", object),
327 Self::PopFromEmptyList => write!(f, "pop from empty list"),
328 }
329 }
330}
331
332impl StdError for Error {}
333
334fn type_to_string(qtype: i8) -> &'static str {
340 match qtype {
341 qtype::BOOL_ATOM => "bool",
342 qtype::GUID_ATOM => "guid",
343 qtype::BYTE_ATOM => "byte",
344 qtype::SHORT_ATOM => "short",
345 qtype::INT_ATOM => "int",
346 qtype::LONG_ATOM => "long",
347 qtype::REAL_ATOM => "real",
348 qtype::FLOAT_ATOM => "float",
349 qtype::CHAR => "char",
350 qtype::SYMBOL_ATOM => "symbol",
351 qtype::TIMESTAMP_ATOM => "timestamp",
352 qtype::MONTH_ATOM => "month",
353 qtype::DATE_ATOM => "date",
354 qtype::DATETIME_ATOM => "datetime",
355 qtype::TIMESPAN_ATOM => "timespan",
356 qtype::MINUTE_ATOM => "minute",
357 qtype::SECOND_ATOM => "second",
358 qtype::TIME_ATOM => "time",
359 qtype::COMPOUND_LIST => "compound list",
360 qtype::BOOL_LIST => "bool list",
361 qtype::GUID_LIST => "guid list",
362 qtype::BYTE_LIST => "byte list",
363 qtype::SHORT_LIST => "short list",
364 qtype::INT_LIST => "int list",
365 qtype::LONG_LIST => "long list",
366 qtype::REAL_LIST => "real list",
367 qtype::FLOAT_LIST => "float list",
368 qtype::STRING => "string",
369 qtype::SYMBOL_LIST => "symbol list",
370 qtype::TIMESTAMP_LIST => "timestamp list",
371 qtype::MONTH_LIST => "month list",
372 qtype::DATE_LIST => "date list",
373 qtype::DATETIME_LIST => "datetime list",
374 qtype::TIMESPAN_LIST => "timespan list",
375 qtype::MINUTE_LIST => "minute list",
376 qtype::SECOND_LIST => "second list",
377 qtype::TIME_LIST => "time list",
378 qtype::TABLE => "table",
379 qtype::DICTIONARY => "dictionary",
380 qtype::NULL => "null",
381 qtype::SORTED_DICTIONARY => "sorted dictionary",
382 qtype::ERROR => "error",
383 _ => "not supported",
384 }
385}