1use alloc::boxed::Box;
2use alloc::string::String;
3
4use crate::{ESExprTag, ESExprTagSet};
5
6#[derive(Debug, Clone)]
8pub struct DecodeError(Box<(DecodeErrorType, DecodeErrorPath)>);
9
10impl DecodeError {
11 #[must_use]
13 pub fn new(error_type: DecodeErrorType, path: DecodeErrorPath) -> Self {
14 DecodeError(Box::new((error_type, path)))
15 }
16
17 #[must_use]
19 pub fn error_type(&self) -> &DecodeErrorType {
20 &self.0.0
21 }
22
23 #[must_use]
25 pub fn error_path(&self) -> &DecodeErrorPath {
26 &self.0.1
27 }
28
29 pub fn error_path_with(&mut self, f: impl FnOnce(DecodeErrorPath) -> DecodeErrorPath) {
31 let mut old_path = DecodeErrorPath::Current;
32 core::mem::swap(&mut old_path, &mut self.0.1);
33 self.0.1 = f(old_path);
34 }
35}
36
37#[derive(Debug, Clone)]
39pub enum DecodeErrorType {
40 UnexpectedExpr {
42 expected_tags: ESExprTagSet,
44
45 actual_tag: ESExprTag<'static>,
47 },
48
49 OutOfRange(String),
51
52 MissingKeyword(String),
54
55 MissingPositional,
57}
58
59#[derive(Debug, Clone)]
61pub enum DecodeErrorPath {
62 Current,
64
65 Constructor(String),
67
68 Positional(String, usize, Box<DecodeErrorPath>),
70
71 Keyword(String, String, Box<DecodeErrorPath>),
73}