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