imdb_index/
error.rs

1use std::fmt;
2use std::path::{Path, PathBuf};
3
4use csv;
5use fst;
6
7/// A type alias for handling errors throughout imdb-index.
8pub type Result<T> = std::result::Result<T, Error>;
9
10/// An error that can occur while interacting with an IMDb index.
11#[derive(Debug)]
12pub struct Error {
13    kind: ErrorKind,
14}
15
16impl Error {
17    /// Return a reference to the kind of this error.
18    pub fn kind(&self) -> &ErrorKind {
19        &self.kind
20    }
21
22    /// Transfer ownership of the kind of this error.
23    pub fn into_kind(self) -> ErrorKind {
24        self.kind
25    }
26
27    pub(crate) fn new(kind: ErrorKind) -> Error {
28        Error { kind }
29    }
30
31    pub(crate) fn unknown_title<T: AsRef<str>>(unk: T) -> Error {
32        Error { kind: ErrorKind::UnknownTitle(unk.as_ref().to_string()) }
33    }
34
35    pub(crate) fn unknown_scorer<T: AsRef<str>>(unk: T) -> Error {
36        Error { kind: ErrorKind::UnknownScorer(unk.as_ref().to_string()) }
37    }
38
39    pub(crate) fn unknown_ngram_type<T: AsRef<str>>(unk: T) -> Error {
40        Error { kind: ErrorKind::UnknownNgramType(unk.as_ref().to_string()) }
41    }
42
43    pub(crate) fn unknown_sim<T: AsRef<str>>(unk: T) -> Error {
44        Error { kind: ErrorKind::UnknownSimilarity(unk.as_ref().to_string()) }
45    }
46
47    pub(crate) fn unknown_directive<T: AsRef<str>>(unk: T) -> Error {
48        Error { kind: ErrorKind::UnknownDirective(unk.as_ref().to_string()) }
49    }
50
51    pub(crate) fn bug<T: AsRef<str>>(msg: T) -> Error {
52        Error { kind: ErrorKind::Bug(msg.as_ref().to_string()) }
53    }
54
55    pub(crate) fn config<T: AsRef<str>>(msg: T) -> Error {
56        Error { kind: ErrorKind::Config(msg.as_ref().to_string()) }
57    }
58
59    pub(crate) fn version(expected: u64, got: u64) -> Error {
60        Error { kind: ErrorKind::VersionMismatch { expected, got } }
61    }
62
63    pub(crate) fn csv(err: csv::Error) -> Error {
64        Error { kind: ErrorKind::Csv(err.to_string()) }
65    }
66
67    pub(crate) fn fst(err: fst::Error) -> Error {
68        Error { kind: ErrorKind::Fst(err.to_string()) }
69    }
70
71    pub(crate) fn io(err: std::io::Error) -> Error {
72        Error { kind: ErrorKind::Io { err, path: None } }
73    }
74
75    pub(crate) fn io_path<P: AsRef<Path>>(
76        err: std::io::Error,
77        path: P,
78    ) -> Error {
79        Error {
80            kind: ErrorKind::Io {
81                err,
82                path: Some(path.as_ref().to_path_buf()),
83            },
84        }
85    }
86
87    pub(crate) fn number<E: std::error::Error + Send + Sync + 'static>(
88        err: E,
89    ) -> Error {
90        Error { kind: ErrorKind::Number(Box::new(err)) }
91    }
92}
93
94impl std::error::Error for Error {
95    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
96        match self.kind {
97            ErrorKind::Io { ref err, .. } => Some(err),
98            ErrorKind::Number(ref err) => Some(&**err),
99            _ => None,
100        }
101    }
102}
103
104impl fmt::Display for Error {
105    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106        self.kind.fmt(f)
107    }
108}
109
110/// The specific kind of error that can occur.
111#[derive(Debug)]
112pub enum ErrorKind {
113    /// An index version mismatch. This error occurs when the version of the
114    /// index is different from the version supported by this version of
115    /// imdb-index.
116    ///
117    /// Generally speaking, the versions must be exactly equivalent, otherwise
118    /// this error is returned.
119    VersionMismatch {
120        /// The expected or supported index version.
121        expected: u64,
122        /// The actual version of the index on disk.
123        got: u64,
124    },
125    /// An error parsing the type of a title.
126    ///
127    /// The data provided is the unrecognized title type.
128    UnknownTitle(String),
129    /// An error parsing the name of a scorer.
130    ///
131    /// The data provided is the unrecognized name.
132    UnknownScorer(String),
133    /// An error parsing the name of an ngram type.
134    ///
135    /// The data provided is the unrecognized name.
136    UnknownNgramType(String),
137    /// An error parsing the name of a similarity function.
138    ///
139    /// The data provided is the unrecognized name.
140    UnknownSimilarity(String),
141    /// An error parsing the name of a directive from a free-form query.
142    ///
143    /// The data provided is the unrecognized name.
144    UnknownDirective(String),
145    /// An unexpected error occurred while reading an index that should not
146    /// have occurred. Generally, these errors correspond to bugs in this
147    /// library.
148    Bug(String),
149    /// An error occurred while reading/writing the index config.
150    Config(String),
151    /// An error that occured while writing or reading CSV data.
152    Csv(String),
153    /// An error that occured while creating an FST index.
154    Fst(String),
155    /// An unexpected I/O error occurred.
156    Io {
157        /// The underlying I/O error.
158        err: std::io::Error,
159        /// A file path, if the I/O error occurred in the context of a named
160        /// file.
161        path: Option<PathBuf>,
162    },
163    /// An error occurred while parsing a number in a free-form query.
164    Number(Box<dyn std::error::Error + Send + Sync>),
165    /// Hints that destructuring should not be exhaustive.
166    ///
167    /// This enum may grow additional variants, so this makes sure clients
168    /// don't count on exhaustive matching. (Otherwise, adding a new variant
169    /// could break existing code.)
170    #[doc(hidden)]
171    __Nonexhaustive,
172}
173
174impl fmt::Display for ErrorKind {
175    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
176        match *self {
177            ErrorKind::VersionMismatch { expected, got } => write!(
178                f,
179                "index version mismatch: expected version {} \
180                           but got version {}. Please rebuild the index.",
181                expected, got
182            ),
183            ErrorKind::UnknownTitle(ref unk) => {
184                write!(f, "unrecognized title type: '{}'", unk)
185            }
186            ErrorKind::UnknownScorer(ref unk) => {
187                write!(f, "unrecognized scorer name: '{}'", unk)
188            }
189            ErrorKind::UnknownNgramType(ref unk) => {
190                write!(f, "unrecognized ngram type: '{}'", unk)
191            }
192            ErrorKind::UnknownSimilarity(ref unk) => {
193                write!(f, "unrecognized similarity function: '{}'", unk)
194            }
195            ErrorKind::UnknownDirective(ref unk) => {
196                write!(f, "unrecognized search directive: '{}'", unk)
197            }
198            ErrorKind::Bug(ref msg) => {
199                let report = "Please report this bug with a backtrace at \
200                              https://github.com/BurntSushi/imdb-rename";
201                write!(f, "BUG: {}\n{}", msg, report)
202            }
203            ErrorKind::Config(ref msg) => write!(f, "config error: {}", msg),
204            ErrorKind::Csv(ref msg) => write!(f, "{}", msg),
205            ErrorKind::Fst(ref msg) => write!(f, "fst error: {}", msg),
206            ErrorKind::Io { path: None, .. } => write!(f, "I/O error"),
207            ErrorKind::Io { path: Some(ref p), .. } => {
208                write!(f, "{}", p.display())
209            }
210            ErrorKind::Number(_) => write!(f, "error parsing number"),
211            ErrorKind::__Nonexhaustive => panic!("invalid error"),
212        }
213    }
214}