config_disassembler/
error.rs1use std::fmt;
4use std::io;
5use std::path::PathBuf;
6
7pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug)]
12pub enum Error {
13 Io(io::Error),
15 Json(serde_json::Error),
17 Json5(json5::Error),
19 Yaml(serde_saphyr::Error),
21 YamlSer(serde_saphyr::SerializeError),
23 TomlDe(toml::de::Error),
25 UnknownFormat(PathBuf),
27 Usage(String),
29 Invalid(String),
31 Xml(String),
33}
34
35impl fmt::Display for Error {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 Error::Io(e) => write!(f, "i/o error: {e}"),
39 Error::Json(e) => write!(f, "json error: {e}"),
40 Error::Json5(e) => write!(f, "json5 error: {e}"),
41 Error::Yaml(e) => write!(f, "yaml error: {e}"),
42 Error::YamlSer(e) => write!(f, "yaml serialize error: {e}"),
43 Error::TomlDe(e) => write!(f, "toml parse error: {e}"),
44 Error::UnknownFormat(p) => {
45 write!(
46 f,
47 "could not determine config format from path: {}",
48 p.display()
49 )
50 }
51 Error::Usage(m) => write!(f, "{m}"),
52 Error::Invalid(m) => write!(f, "{m}"),
53 Error::Xml(m) => write!(f, "xml-disassembler: {m}"),
54 }
55 }
56}
57
58impl std::error::Error for Error {
59 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
60 match self {
61 Error::Io(e) => Some(e),
62 Error::Json(e) => Some(e),
63 Error::Json5(e) => Some(e),
64 Error::Yaml(e) => Some(e),
65 Error::YamlSer(e) => Some(e),
66 Error::TomlDe(e) => Some(e),
67 _ => None,
68 }
69 }
70}
71
72impl From<io::Error> for Error {
73 fn from(e: io::Error) -> Self {
74 Error::Io(e)
75 }
76}
77
78impl From<serde_json::Error> for Error {
79 fn from(e: serde_json::Error) -> Self {
80 Error::Json(e)
81 }
82}
83
84impl From<json5::Error> for Error {
85 fn from(e: json5::Error) -> Self {
86 Error::Json5(e)
87 }
88}
89
90impl From<serde_saphyr::Error> for Error {
91 fn from(e: serde_saphyr::Error) -> Self {
92 Error::Yaml(e)
93 }
94}
95
96impl From<serde_saphyr::SerializeError> for Error {
97 fn from(e: serde_saphyr::SerializeError) -> Self {
98 Error::YamlSer(e)
99 }
100}
101
102impl From<toml::de::Error> for Error {
103 fn from(e: toml::de::Error) -> Self {
104 Error::TomlDe(e)
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111 use std::error::Error as _;
112
113 #[test]
114 fn display_covers_all_variants() {
115 let e = Error::UnknownFormat(PathBuf::from("foo.txt"));
116 assert!(e.to_string().contains("foo.txt"));
117 assert!(Error::Usage("u".into()).to_string().contains("u"));
118 assert!(Error::Invalid("i".into()).to_string().contains("i"));
119 assert!(Error::Xml("x".into()).to_string().contains("xml"));
120
121 let io_err = Error::from(io::Error::new(io::ErrorKind::NotFound, "missing"));
122 assert!(io_err.to_string().contains("i/o error"));
123 assert!(io_err.source().is_some());
124
125 let json_err: Error = serde_json::from_str::<serde_json::Value>("{ not json")
126 .unwrap_err()
127 .into();
128 assert!(json_err.to_string().contains("json"));
129 assert!(json_err.source().is_some());
130
131 let yaml_err: Error = serde_saphyr::from_str::<serde_json::Value>("key: [unclosed")
132 .unwrap_err()
133 .into();
134 assert!(yaml_err.to_string().contains("yaml"));
135 assert!(yaml_err.source().is_some());
136
137 let yaml_ser_err: Error =
138 <serde_saphyr::SerializeError as serde::ser::Error>::custom("bad").into();
139 assert!(yaml_ser_err.to_string().contains("yaml serialize"));
140 assert!(yaml_ser_err.source().is_some());
141
142 let json5_err: Error = json5::from_str::<serde_json::Value>("{ not json5")
143 .unwrap_err()
144 .into();
145 assert!(json5_err.to_string().contains("json5"));
146 assert!(json5_err.source().is_some());
147
148 let toml_de_err: Error = toml::from_str::<serde_json::Value>("not = = toml")
149 .unwrap_err()
150 .into();
151 assert!(toml_de_err.to_string().contains("toml"));
152 assert!(toml_de_err.source().is_some());
153
154 assert!(Error::Usage("u".into()).source().is_none());
156 }
157}