serde_device_tree/
error.rs

1// Copyright (c) 2021 HUST IoT Security Lab
2// serde_device_tree is licensed under Mulan PSL v2.
3// You can use this software according to the terms and conditions of the Mulan PSL v2.
4// You may obtain a copy of Mulan PSL v2 at:
5//          http://license.coscl.org.cn/MulanPSL2
6// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
7// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
8// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
9// See the Mulan PSL v2 for more details.
10
11#[cfg(feature = "alloc")]
12use alloc::{format, string::String};
13use core::fmt;
14
15#[derive(Clone, Debug)]
16pub enum Error {
17    Typed {
18        error_type: ErrorType,
19        file_index: usize,
20    },
21    #[cfg(feature = "alloc")]
22    Custom(String),
23    #[cfg(not(feature = "alloc"))]
24    Custom,
25}
26
27#[derive(Debug, Clone, Copy)]
28pub enum ErrorType {
29    InvalidMagic {
30        wrong_magic: u32,
31    },
32    IncompatibleVersion {
33        last_comp_version: u32,
34        library_supported_version: u32,
35    },
36    HeaderTooShort {
37        header_length: u32,
38        at_least_length: u32,
39    },
40    StructureIndex {
41        current_index: u32,
42        bound_index: u32,
43        structure_or_string: bool,
44        overflow_or_underflow: bool,
45    },
46    StringEofUnexpected,
47    SliceEofUnexpected {
48        expected_length: u32,
49        remaining_length: u32,
50    },
51    TableStringOffset {
52        given_offset: u32,
53        bound_offset: u32,
54    },
55    TagEofUnexpected {
56        current_index: u32,
57        bound_index: u32,
58    },
59    InvalidTagId {
60        wrong_id: u32,
61    },
62    ExpectStructBegin,
63    ExpectStructEnd,
64    NoRemainingTags,
65    InvalidSerdeTypeLength {
66        expected_length: u8,
67    },
68    Utf8(core::str::Utf8Error),
69}
70
71impl Error {
72    #[inline]
73    pub fn invalid_magic(wrong_magic: u32, file_index: usize) -> Error {
74        Error::Typed {
75            error_type: ErrorType::InvalidMagic { wrong_magic },
76            file_index,
77        }
78    }
79    #[inline]
80    pub fn incompatible_version(
81        last_comp_version: u32,
82        library_supported_version: u32,
83        file_index: usize,
84    ) -> Error {
85        Error::Typed {
86            error_type: ErrorType::IncompatibleVersion {
87                last_comp_version,
88                library_supported_version,
89            },
90            file_index,
91        }
92    }
93    #[inline]
94    pub fn header_too_short(header_length: u32, at_least_length: u32, file_index: usize) -> Error {
95        Error::Typed {
96            error_type: ErrorType::HeaderTooShort {
97                header_length,
98                at_least_length,
99            },
100            file_index,
101        }
102    }
103    #[inline]
104    pub fn structure_index_underflow(
105        begin_index: u32,
106        at_least_index: u32,
107        file_index: usize,
108    ) -> Error {
109        Error::Typed {
110            error_type: ErrorType::StructureIndex {
111                current_index: begin_index,
112                bound_index: at_least_index,
113                structure_or_string: true,
114                overflow_or_underflow: false,
115            },
116            file_index,
117        }
118    }
119    #[inline]
120    pub fn structure_index_overflow(
121        end_index: u32,
122        at_most_index: u32,
123        file_index: usize,
124    ) -> Error {
125        Error::Typed {
126            error_type: ErrorType::StructureIndex {
127                current_index: end_index,
128                bound_index: at_most_index,
129                structure_or_string: true,
130                overflow_or_underflow: true,
131            },
132            file_index,
133        }
134    }
135    #[inline]
136    pub fn string_index_underflow(
137        begin_index: u32,
138        at_least_index: u32,
139        file_index: usize,
140    ) -> Error {
141        Error::Typed {
142            error_type: ErrorType::StructureIndex {
143                current_index: begin_index,
144                bound_index: at_least_index,
145                structure_or_string: false,
146                overflow_or_underflow: false,
147            },
148            file_index,
149        }
150    }
151    #[inline]
152    pub fn string_index_overflow(end_index: u32, at_most_index: u32, file_index: usize) -> Error {
153        Error::Typed {
154            error_type: ErrorType::StructureIndex {
155                current_index: end_index,
156                bound_index: at_most_index,
157                structure_or_string: false,
158                overflow_or_underflow: true,
159            },
160            file_index,
161        }
162    }
163    #[inline]
164    pub fn string_eof_unpexpected(file_index: usize) -> Error {
165        Error::Typed {
166            error_type: ErrorType::StringEofUnexpected,
167            file_index,
168        }
169    }
170    #[inline]
171    pub fn slice_eof_unpexpected(
172        expected_length: u32,
173        remaining_length: u32,
174        file_index: usize,
175    ) -> Error {
176        Error::Typed {
177            error_type: ErrorType::SliceEofUnexpected {
178                expected_length,
179                remaining_length,
180            },
181            file_index,
182        }
183    }
184    #[inline]
185    pub fn table_string_offset(given_offset: u32, bound_offset: u32, file_index: usize) -> Error {
186        Error::Typed {
187            error_type: ErrorType::TableStringOffset {
188                given_offset,
189                bound_offset,
190            },
191            file_index,
192        }
193    }
194    #[inline]
195    pub fn tag_eof_unexpected(current_index: u32, bound_index: u32, file_index: usize) -> Error {
196        Error::Typed {
197            error_type: ErrorType::TagEofUnexpected {
198                current_index,
199                bound_index,
200            },
201            file_index,
202        }
203    }
204    #[inline]
205    pub fn invalid_tag_id(wrong_id: u32, file_index: usize) -> Error {
206        Error::Typed {
207            error_type: ErrorType::InvalidTagId { wrong_id },
208            file_index,
209        }
210    }
211    #[inline]
212    pub fn invalid_serde_type_length(expected_length: u8, file_index: usize) -> Error {
213        Error::Typed {
214            error_type: ErrorType::InvalidSerdeTypeLength { expected_length },
215            file_index,
216        }
217    }
218    #[inline]
219    pub fn utf8(error: core::str::Utf8Error, file_index: usize) -> Error {
220        Error::Typed {
221            error_type: ErrorType::Utf8(error),
222            file_index,
223        }
224    }
225    #[inline]
226    pub fn expected_struct_begin() -> Error {
227        Error::Typed {
228            error_type: ErrorType::ExpectStructBegin,
229            file_index: 0,
230        }
231    }
232    #[inline]
233    pub fn expected_struct_end() -> Error {
234        Error::Typed {
235            error_type: ErrorType::ExpectStructEnd,
236            file_index: 0,
237        }
238    }
239    #[inline]
240    pub fn no_remaining_tags() -> Error {
241        Error::Typed {
242            error_type: ErrorType::NoRemainingTags,
243            file_index: 0,
244        }
245    }
246}
247
248pub type Result<T> = core::result::Result<T, Error>;
249
250impl serde::de::Error for Error {
251    fn custom<T>(msg: T) -> Self
252    where
253        T: fmt::Display,
254    {
255        #[cfg(feature = "alloc")]
256        {
257            Self::Custom(format!("{}", msg))
258        }
259
260        #[cfg(not(feature = "alloc"))]
261        {
262            let _ = msg; // todo
263            Self::Custom
264        }
265    }
266}
267
268#[cfg(feature = "std")]
269impl std::error::Error for Error {}
270
271impl fmt::Display for Error {
272    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
273        match self {
274            Error::Typed {
275                error_type: ErrorType::InvalidMagic { wrong_magic },
276                file_index,
277            } => write!(
278                f,
279                "Error(invalid magic, value: {}, index: {})",
280                wrong_magic, file_index
281            ),
282            // todo: format other error types
283            others => write!(f, "{:?}", others),
284        }
285    }
286}