use std::fmt;
use std::path::{Path, PathBuf};
use csv;
use fst;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl Error {
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
pub fn into_kind(self) -> ErrorKind {
self.kind
}
pub(crate) fn new(kind: ErrorKind) -> Error {
Error { kind }
}
pub(crate) fn unknown_title<T: AsRef<str>>(unk: T) -> Error {
Error { kind: ErrorKind::UnknownTitle(unk.as_ref().to_string()) }
}
pub(crate) fn unknown_scorer<T: AsRef<str>>(unk: T) -> Error {
Error { kind: ErrorKind::UnknownScorer(unk.as_ref().to_string()) }
}
pub(crate) fn unknown_ngram_type<T: AsRef<str>>(unk: T) -> Error {
Error { kind: ErrorKind::UnknownNgramType(unk.as_ref().to_string()) }
}
pub(crate) fn unknown_sim<T: AsRef<str>>(unk: T) -> Error {
Error { kind: ErrorKind::UnknownSimilarity(unk.as_ref().to_string()) }
}
pub(crate) fn unknown_directive<T: AsRef<str>>(unk: T) -> Error {
Error { kind: ErrorKind::UnknownDirective(unk.as_ref().to_string()) }
}
pub(crate) fn bug<T: AsRef<str>>(msg: T) -> Error {
Error { kind: ErrorKind::Bug(msg.as_ref().to_string()) }
}
pub(crate) fn config<T: AsRef<str>>(msg: T) -> Error {
Error { kind: ErrorKind::Config(msg.as_ref().to_string()) }
}
pub(crate) fn version(expected: u64, got: u64) -> Error {
Error { kind: ErrorKind::VersionMismatch { expected, got } }
}
pub(crate) fn csv(err: csv::Error) -> Error {
Error { kind: ErrorKind::Csv(err.to_string()) }
}
pub(crate) fn fst(err: fst::Error) -> Error {
Error { kind: ErrorKind::Fst(err.to_string()) }
}
pub(crate) fn io(err: std::io::Error) -> Error {
Error { kind: ErrorKind::Io { err, path: None } }
}
pub(crate) fn io_path<P: AsRef<Path>>(
err: std::io::Error,
path: P,
) -> Error {
Error {
kind: ErrorKind::Io {
err,
path: Some(path.as_ref().to_path_buf()),
},
}
}
pub(crate) fn number<E: std::error::Error + Send + Sync + 'static>(
err: E,
) -> Error {
Error { kind: ErrorKind::Number(Box::new(err)) }
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self.kind {
ErrorKind::Io { ref err, .. } => Some(err),
ErrorKind::Number(ref err) => Some(&**err),
_ => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.kind.fmt(f)
}
}
#[derive(Debug)]
pub enum ErrorKind {
VersionMismatch {
expected: u64,
got: u64,
},
UnknownTitle(String),
UnknownScorer(String),
UnknownNgramType(String),
UnknownSimilarity(String),
UnknownDirective(String),
Bug(String),
Config(String),
Csv(String),
Fst(String),
Io {
err: std::io::Error,
path: Option<PathBuf>,
},
Number(Box<dyn std::error::Error + Send + Sync>),
#[doc(hidden)]
__Nonexhaustive,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ErrorKind::VersionMismatch { expected, got } => write!(
f,
"index version mismatch: expected version {} \
but got version {}. Please rebuild the index.",
expected, got
),
ErrorKind::UnknownTitle(ref unk) => {
write!(f, "unrecognized title type: '{}'", unk)
}
ErrorKind::UnknownScorer(ref unk) => {
write!(f, "unrecognized scorer name: '{}'", unk)
}
ErrorKind::UnknownNgramType(ref unk) => {
write!(f, "unrecognized ngram type: '{}'", unk)
}
ErrorKind::UnknownSimilarity(ref unk) => {
write!(f, "unrecognized similarity function: '{}'", unk)
}
ErrorKind::UnknownDirective(ref unk) => {
write!(f, "unrecognized search directive: '{}'", unk)
}
ErrorKind::Bug(ref msg) => {
let report = "Please report this bug with a backtrace at \
https://github.com/BurntSushi/imdb-rename";
write!(f, "BUG: {}\n{}", msg, report)
}
ErrorKind::Config(ref msg) => write!(f, "config error: {}", msg),
ErrorKind::Csv(ref msg) => write!(f, "{}", msg),
ErrorKind::Fst(ref msg) => write!(f, "fst error: {}", msg),
ErrorKind::Io { path: None, .. } => write!(f, "I/O error"),
ErrorKind::Io { path: Some(ref p), .. } => {
write!(f, "{}", p.display())
}
ErrorKind::Number(_) => write!(f, "error parsing number"),
ErrorKind::__Nonexhaustive => panic!("invalid error"),
}
}
}