1use std::fmt::{self, Debug, Display};
2use std::io;
3use std::path::Path;
4
5pub struct Error {
8 pub(crate) e: Box<ErrorImpl>,
9}
10
11pub type Result<T> = std::result::Result<T, Error>;
13
14pub(crate) struct ErrorImpl {
15 pub(crate) path: Option<&'static Path>,
16 kind: ErrorKind,
17}
18
19pub(crate) enum ErrorKind {
20 Msg(String),
21 Csv(csv::Error),
22 Io(io::Error),
23 Json(serde_json::Error),
24}
25
26impl std::error::Error for Error {
27 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
28 match &self.e.kind {
29 ErrorKind::Msg(_) => None,
30 ErrorKind::Io(e) => e.source(),
31 ErrorKind::Csv(e) => e.source(),
32 ErrorKind::Json(e) => e.source(),
33 }
34 }
35}
36
37impl Display for Error {
38 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
39 if let Some(path) = self.e.path {
40 write!(f, "{}.csv: ", path.display())?;
41 }
42 match &self.e.kind {
43 ErrorKind::Msg(e) => f.write_str(e),
44 ErrorKind::Io(e) => write!(f, "{}", e),
45 ErrorKind::Csv(e) => write!(f, "{}", e),
46 ErrorKind::Json(e) => write!(f, "{}", e),
47 }
48 }
49}
50
51impl Debug for Error {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 write!(f, "db_dump::Error({:?})", self.to_string())
54 }
55}
56
57pub(crate) fn err(variant: impl Into<ErrorKind>) -> Error {
58 Error {
59 e: Box::new(ErrorImpl {
60 path: None,
61 kind: variant.into(),
62 }),
63 }
64}
65
66impl<'a> From<fmt::Arguments<'a>> for ErrorKind {
67 fn from(e: fmt::Arguments) -> Self {
68 ErrorKind::Msg(e.to_string())
69 }
70}
71
72impl From<csv::Error> for ErrorKind {
73 fn from(e: csv::Error) -> Self {
74 ErrorKind::Csv(e)
75 }
76}
77
78impl From<io::Error> for Error {
79 fn from(e: io::Error) -> Self {
80 Error {
81 e: Box::new(ErrorImpl {
82 path: None,
83 kind: ErrorKind::Io(e),
84 }),
85 }
86 }
87}
88
89impl From<serde_json::Error> for ErrorKind {
90 fn from(e: serde_json::Error) -> Self {
91 ErrorKind::Json(e)
92 }
93}