1#[derive(Copy, Clone, Debug)]
3pub struct Error {
4 pub source_location: ErrorLocation,
6 pub error_kind: ErrorKind,
8}
9
10impl core::fmt::Display for Error {
11 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12 write!(f, "In {}: {}", self.source_location, self.error_kind)
13 }
14}
15
16#[cfg(feature = "std")]
17impl std::error::Error for Error {
18 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
19 Some(&self.error_kind)
20 }
21}
22
23#[derive(Copy, Clone, Debug)]
25#[non_exhaustive]
26pub enum ErrorKind {
27 InvalidOffset,
29 InvalidLength,
31 UnionVectorLengthsMismatched {
33 tags_len: usize,
35 values_len: usize,
37 },
38 UnknownEnumTag {
41 source: UnknownEnumTagKind,
43 },
44 UnknownUnionTag {
47 tag: u8,
49 },
50 InvalidVtableLength {
52 length: u16,
54 },
55 InvalidUtf8 {
57 source: core::str::Utf8Error,
59 },
60 MissingRequired,
62 MissingNullTerminator,
64}
65
66impl core::fmt::Display for ErrorKind {
67 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
68 match self {
69 ErrorKind::InvalidOffset => write!(f, "Invalid offset"),
70 ErrorKind::InvalidLength => write!(f, "Invalid length"),
71 ErrorKind::UnionVectorLengthsMismatched {
72 tags_len,
73 values_len,
74 } => {
75 write!(f, "Mismatched lengths between tag and value vectors. Length of tags = {tags_len}, length of values = {values_len}")
76 }
77 ErrorKind::UnknownEnumTag { source } => source.fmt(f),
78 ErrorKind::UnknownUnionTag { tag } => write!(f, "Unknown union (tag = {tag})"),
79 ErrorKind::InvalidVtableLength { length } => {
80 write!(f, "Invalid vtable length (length = {length})")
81 }
82 ErrorKind::InvalidUtf8 { source } => write!(f, "Invalid utf-8: {source}"),
83 ErrorKind::MissingRequired => write!(f, "Missing required field"),
84 ErrorKind::MissingNullTerminator => write!(f, "Missing null terminator"),
85 }
86 }
87}
88
89#[cfg(feature = "std")]
90impl std::error::Error for ErrorKind {
91 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
92 match self {
93 ErrorKind::InvalidOffset => None,
94 ErrorKind::InvalidLength => None,
95 ErrorKind::UnionVectorLengthsMismatched { .. } => None,
96 ErrorKind::UnknownEnumTag { source } => Some(source),
97 ErrorKind::UnknownUnionTag { .. } => None,
98 ErrorKind::InvalidVtableLength { .. } => None,
99 ErrorKind::InvalidUtf8 { source } => Some(source),
100 ErrorKind::MissingRequired => None,
101 ErrorKind::MissingNullTerminator => None,
102 }
103 }
104}
105
106impl From<UnknownEnumTagKind> for ErrorKind {
107 fn from(source: UnknownEnumTagKind) -> Self {
108 ErrorKind::UnknownEnumTag { source }
109 }
110}
111
112impl From<core::str::Utf8Error> for ErrorKind {
113 fn from(source: core::str::Utf8Error) -> Self {
114 ErrorKind::InvalidUtf8 { source }
115 }
116}
117
118#[derive(Clone, Debug)]
119pub struct UnknownEnumTag {
124 pub source_location: ErrorLocation,
126 pub error_kind: UnknownEnumTagKind,
128}
129
130impl core::fmt::Display for UnknownEnumTag {
131 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
132 write!(f, "In {}: {}", self.source_location, self.error_kind)
133 }
134}
135
136#[cfg(feature = "std")]
137impl std::error::Error for UnknownEnumTag {
138 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
139 Some(&self.error_kind)
140 }
141}
142
143#[derive(Copy, Clone, Debug)]
144pub struct UnknownEnumTagKind {
146 pub tag: i128,
148}
149
150impl core::fmt::Display for UnknownEnumTagKind {
151 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
152 write!(f, "Unknown enum (tag = {})", self.tag)
153 }
154}
155
156#[cfg(feature = "std")]
157impl std::error::Error for UnknownEnumTagKind {}
158
159#[derive(Copy, Clone, Debug)]
160pub struct ErrorLocation {
163 pub type_: &'static str,
165 pub method: &'static str,
167 pub byte_offset: usize,
169}
170
171impl core::fmt::Display for ErrorLocation {
172 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
173 if self.byte_offset != usize::MAX {
174 write!(
175 f,
176 "<{}@{:x}>::{}()",
177 self.type_, self.byte_offset, self.method,
178 )
179 } else {
180 write!(f, "<{}>::{}()", self.type_, self.method,)
181 }
182 }
183}
184
185impl From<UnknownEnumTag> for Error {
186 fn from(error: UnknownEnumTag) -> Self {
187 Self {
188 source_location: error.source_location,
189 error_kind: error.error_kind.into(),
190 }
191 }
192}
193
194impl From<core::convert::Infallible> for Error {
195 fn from(value: core::convert::Infallible) -> Self {
196 match value {}
197 }
198}
199
200impl UnknownEnumTagKind {
201 pub fn with_error_location(
203 self,
204 type_: &'static str,
205 method: &'static str,
206 byte_offset: usize,
207 ) -> UnknownEnumTag {
208 UnknownEnumTag {
209 source_location: ErrorLocation {
210 type_,
211 method,
212 byte_offset,
213 },
214 error_kind: self,
215 }
216 }
217}
218
219impl ErrorKind {
220 pub fn with_error_location(
222 self,
223 type_: &'static str,
224 method: &'static str,
225 byte_offset: usize,
226 ) -> Error {
227 Error {
228 source_location: ErrorLocation {
229 type_,
230 method,
231 byte_offset,
232 },
233 error_kind: self,
234 }
235 }
236}