1#![warn(missing_docs)]
3#![warn(unsafe_code)]
4use std::{
5 fmt::{Debug, Display, Formatter, Result},
6 io,
7};
8
9pub struct Error {
12 kind: ErrorKind,
13 }
17
18impl Debug for Error {
19 fn fmt(&self, f: &mut Formatter) -> Result {
20 write!(f, "{}", self.kind)
21 }
22}
23
24impl Display for Error {
25 fn fmt(&self, f: &mut Formatter) -> Result {
26 write!(f, "{}", self.kind)
27 }
28}
29
30impl std::error::Error for Error {
31 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
32 match self.kind {
33 ErrorKind::IO(ref io) => Some(io),
34 _ => None,
35 }
36 }
37}
38
39impl Error {
40 pub fn new(kind: ErrorKind) -> Error {
42 Error { kind }
43 }
44}
45
46impl From<nom::Err<nom::error::Error<&[u8]>>> for Error {
47 fn from(e: nom::Err<nom::error::Error<&[u8]>>) -> Self {
48 Error::new(ErrorKind::new(&e.to_string()))
49 }
50}
51
52impl<'a> nom::error::ParseError<&'a [u8]> for Error {
59 fn from_error_kind(_input: &'a [u8], kind: nom::error::ErrorKind) -> Self {
60 Error::new(ErrorKind::new(kind.description()))
61 }
62
63 fn append(_input: &'a [u8], _kind: nom::error::ErrorKind, other: Self) -> Self {
64 other
65 }
66}
67
68impl From<std::io::Error> for Error {
69 fn from(e: std::io::Error) -> Self {
70 Error::new(ErrorKind::IO(e))
71 }
72}
73
74#[derive(Debug)]
77pub enum ErrorKind {
78 Message(String),
80
81 Invalid(InvalidErrorKind),
84
85 Unimplemented(String),
88
89 NotFound(String),
93
94 IO(io::Error),
98}
99
100impl Display for ErrorKind {
101 fn fmt(&self, f: &mut Formatter) -> Result {
102 match self {
103 ErrorKind::Message(message) => write!(f, "An error occurred: {}", message),
104 ErrorKind::Invalid(e) => write!(f, "{}", e),
105 ErrorKind::Unimplemented(message) => {
106 write!(f, "Unimplemented feature: {}", message)
107 }
108 ErrorKind::NotFound(message) => {
109 write!(f, "Data not found: {}", message)
110 }
111 ErrorKind::IO(io) => {
112 write!(f, "IO error: {}", io)
113 }
114 }
115 }
116}
117
118impl ErrorKind {
119 pub fn new(message: &str) -> ErrorKind {
121 ErrorKind::Message(message.to_string())
122 }
123}
124
125#[derive(Debug, Eq, PartialEq)]
127pub enum InvalidErrorKind {
128 Invalid(String),
130 Checksum,
132}
133
134impl Display for InvalidErrorKind {
135 fn fmt(&self, f: &mut Formatter) -> Result {
136 match self {
137 InvalidErrorKind::Invalid(message) => write!(f, "Image is invalid: {}", message),
138 InvalidErrorKind::Checksum => write!(f, "Image has an invalid checksum"),
139 }
140 }
141}
142
143#[allow(unused_imports)]
145#[cfg(test)]
146pub mod tests {
147 use crate::error::ErrorKind;
148
149 #[test]
151 pub fn error_kind_new_works() {
152 let ek1 = ErrorKind::new("Test1");
153 let ek2 = ErrorKind::new("Test1");
154
155 matches!(ek1, ErrorKind::Message(x) if x == "Test1");
156 matches!(ek2, ErrorKind::Message(x) if x == "Test1");
157 }
158
159 #[test]
161 pub fn error_kind_not_found_works() {
162 let ek = ErrorKind::NotFound(String::from("Test1"));
163 matches!(ek, ErrorKind::NotFound(x) if x == "Test1");
164 }
165}