1use std::fmt;
2use std::path::{Path, PathBuf};
3
4use csv;
5use fst;
6
7pub type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug)]
12pub struct Error {
13 kind: ErrorKind,
14}
15
16impl Error {
17 pub fn kind(&self) -> &ErrorKind {
19 &self.kind
20 }
21
22 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#[derive(Debug)]
112pub enum ErrorKind {
113 VersionMismatch {
120 expected: u64,
122 got: u64,
124 },
125 UnknownTitle(String),
129 UnknownScorer(String),
133 UnknownNgramType(String),
137 UnknownSimilarity(String),
141 UnknownDirective(String),
145 Bug(String),
149 Config(String),
151 Csv(String),
153 Fst(String),
155 Io {
157 err: std::io::Error,
159 path: Option<PathBuf>,
162 },
163 Number(Box<dyn std::error::Error + Send + Sync>),
165 #[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}