1#[derive(Debug)]
2pub enum Error {
3 Io(std::io::Error),
4 Decode(buffa::DecodeError),
5 Json(serde_json::Error),
6 Codegen(String),
7}
8
9impl std::fmt::Display for Error {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 match self {
12 Error::Io(e) => write!(f, "io error: {e}"),
13 Error::Decode(e) => write!(f, "proto decode error: {e}"),
14 Error::Json(e) => write!(f, "json error: {e}"),
15 Error::Codegen(msg) => write!(f, "codegen error: {msg}"),
16 }
17 }
18}
19
20impl std::error::Error for Error {
21 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
22 match self {
23 Error::Io(e) => Some(e),
24 Error::Decode(e) => Some(e),
25 Error::Json(e) => Some(e),
26 Error::Codegen(_) => None,
27 }
28 }
29}
30
31impl From<std::io::Error> for Error {
32 fn from(e: std::io::Error) -> Self {
33 Self::Io(e)
34 }
35}
36
37impl From<buffa::DecodeError> for Error {
38 fn from(e: buffa::DecodeError) -> Self {
39 Self::Decode(e)
40 }
41}
42
43impl From<serde_json::Error> for Error {
44 fn from(e: serde_json::Error) -> Self {
45 Self::Json(e)
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn display_io_error() {
55 let e = Error::Io(std::io::Error::new(
56 std::io::ErrorKind::NotFound,
57 "file missing",
58 ));
59 assert!(e.to_string().contains("file missing"));
60 }
61
62 #[test]
63 fn display_codegen_error() {
64 let e = Error::Codegen("unknown type: foo".to_string());
65 assert!(e.to_string().contains("unknown type: foo"));
66 }
67
68 #[test]
69 fn from_io() {
70 let io_err = std::io::Error::new(std::io::ErrorKind::BrokenPipe, "pipe broken");
71 let e: Error = io_err.into();
72 assert!(matches!(e, Error::Io(_)));
73 }
74
75 #[test]
76 fn from_json() {
77 let json_err = serde_json::from_str::<serde_json::Value>("bad json").unwrap_err();
78 let e: Error = json_err.into();
79 assert!(matches!(e, Error::Json(_)));
80 }
81}