db_dump/
error.rs

1use std::fmt::{self, Debug, Display};
2use std::io;
3use std::path::Path;
4
5/// Error type returned by `db_dump::load_all` and `Loader::load` in the event
6/// that loading crates.io's DB dump from the specified file fails.
7pub struct Error {
8    pub(crate) e: Box<ErrorImpl>,
9}
10
11/// Result type returned by `db_dump::load_all` and `Loader::load`.
12pub 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}