Skip to main content

serde_toon/
error.rs

1use std::error::Error as StdError;
2
3use thiserror::Error as ThisError;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum ErrorKind {
7    NotImplemented,
8    Encode,
9    Decode,
10    Serialize,
11    Deserialize,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum ErrorStage {
16    Encode,
17    Decode,
18    Unknown,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct Location {
23    pub offset: usize,
24    pub line: usize,
25    pub column: usize,
26}
27
28#[derive(Debug, ThisError)]
29#[error("{message}")]
30pub struct Error {
31    pub kind: ErrorKind,
32    pub stage: ErrorStage,
33    pub message: String,
34    pub location: Option<Location>,
35    #[source]
36    source: Option<Box<dyn StdError + Send + Sync + 'static>>,
37}
38
39impl Error {
40    pub fn not_implemented(context: &'static str) -> Self {
41        Self::new(
42            ErrorKind::NotImplemented,
43            ErrorStage::Unknown,
44            format!("not implemented: {context}"),
45        )
46    }
47
48    pub fn encode(message: impl Into<String>) -> Self {
49        Self::new(ErrorKind::Encode, ErrorStage::Encode, message)
50    }
51
52    pub fn encode_with_source(
53        message: impl Into<String>,
54        source: impl StdError + Send + Sync + 'static,
55    ) -> Self {
56        Self::new_with_source(ErrorKind::Encode, ErrorStage::Encode, message, source)
57    }
58
59    pub fn decode(message: impl Into<String>) -> Self {
60        Self::new(ErrorKind::Decode, ErrorStage::Decode, message)
61    }
62
63    pub fn decode_with_source(
64        message: impl Into<String>,
65        source: impl StdError + Send + Sync + 'static,
66    ) -> Self {
67        Self::new_with_source(ErrorKind::Decode, ErrorStage::Decode, message, source)
68    }
69
70    pub fn serialize(message: impl Into<String>) -> Self {
71        Self::new(ErrorKind::Serialize, ErrorStage::Encode, message)
72    }
73
74    pub fn serialize_with_source(
75        message: impl Into<String>,
76        source: impl StdError + Send + Sync + 'static,
77    ) -> Self {
78        Self::new_with_source(ErrorKind::Serialize, ErrorStage::Encode, message, source)
79    }
80
81    pub fn deserialize(message: impl Into<String>) -> Self {
82        Self::new(ErrorKind::Deserialize, ErrorStage::Decode, message)
83    }
84
85    pub fn deserialize_with_source(
86        message: impl Into<String>,
87        source: impl StdError + Send + Sync + 'static,
88    ) -> Self {
89        Self::new_with_source(ErrorKind::Deserialize, ErrorStage::Decode, message, source)
90    }
91
92    pub fn with_stage(mut self, stage: ErrorStage) -> Self {
93        self.stage = stage;
94        self
95    }
96
97    pub fn with_source(mut self, source: impl StdError + Send + Sync + 'static) -> Self {
98        self.source = Some(Box::new(source));
99        self
100    }
101
102    pub fn with_location(mut self, location: Location) -> Self {
103        self.location = Some(location);
104        self
105    }
106
107    fn new(kind: ErrorKind, stage: ErrorStage, message: impl Into<String>) -> Self {
108        Self {
109            kind,
110            stage,
111            message: message.into(),
112            location: None,
113            source: None,
114        }
115    }
116
117    fn new_with_source(
118        kind: ErrorKind,
119        stage: ErrorStage,
120        message: impl Into<String>,
121        source: impl StdError + Send + Sync + 'static,
122    ) -> Self {
123        Self {
124            kind,
125            stage,
126            message: message.into(),
127            location: None,
128            source: Some(Box::new(source)),
129        }
130    }
131}