diff --git a/Cargo.lock b/Cargo.lock index 0bf2ec4..7583e84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,6 +702,24 @@ dependencies = [ "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thiserror" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -736,6 +754,7 @@ dependencies = [ "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -972,6 +991,8 @@ dependencies = [ "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thiserror 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fe148fa0fc3363a27092d48f7787363ded15bb8623c5d5dd4e2e9f23e4b21bc" +"checksum thiserror-impl 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "258da67e99e590650fa541ac6be764313d23e80cefb6846b516deb8de6b6d921" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" "checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" diff --git a/typos/Cargo.toml b/typos/Cargo.toml index 9736360..8f7b7e9 100644 --- a/typos/Cargo.toml +++ b/typos/Cargo.toml @@ -16,6 +16,7 @@ codecov = { repository = "crate-ci/typos" } [dependencies] anyhow = "1.0" +thiserror = "1.0" regex = "1.0" lazy_static = "1.2.0" serde = { version = "1.0", features = ["derive"] } diff --git a/typos/src/checks.rs b/typos/src/checks.rs index 04193c5..4d101bf 100644 --- a/typos/src/checks.rs +++ b/typos/src/checks.rs @@ -70,7 +70,7 @@ impl<'d, 'p> Checks<'d, 'p> { &self, path: &std::path::Path, report: report::Report, - ) -> Result { + ) -> Result { let mut typos_found = false; if !self.check_filenames { @@ -113,14 +113,15 @@ impl<'d, 'p> Checks<'d, 'p> { path: &std::path::Path, explicit: bool, report: report::Report, - ) -> Result { + ) -> Result { let mut typos_found = false; if !self.check_files { return Ok(typos_found); } - let buffer = std::fs::read(path)?; + let buffer = std::fs::read(path) + .map_err(|e| crate::ErrorKind::IoError.into_error().with_source(e))?; let null_max = std::cmp::min(buffer.len(), 1024); if !explicit && !self.binary && buffer[0..null_max].find_byte(b'\0').is_some() { let msg = report::BinaryFile { diff --git a/typos/src/error.rs b/typos/src/error.rs new file mode 100644 index 0000000..3d49ded --- /dev/null +++ b/typos/src/error.rs @@ -0,0 +1,52 @@ +#[derive(Debug, Clone, Copy, derive_more::Display)] +pub enum ErrorKind { + #[display(fmt = "Invalid word")] + InvalidWord, + #[display(fmt = "IO Error")] + IoError, +} + +impl ErrorKind { + pub fn into_error(self) -> Error { + Error { + kind: self, + msg: None, + source: None, + } + } +} + +#[derive(thiserror::Error, Debug)] +pub struct Error { + kind: ErrorKind, + msg: Option, + source: Option, +} + +impl Error { + pub fn with_message(mut self, msg: String) -> Self { + self.msg = Some(msg); + self + } + + pub fn with_source( + mut self, + source: E, + ) -> Self { + self.source = Some(source.into()); + self + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { + if let Some(msg) = self.msg.as_ref() { + write!(f, "{}: {}", self.kind, msg)?; + } else if let Some(source) = self.source.as_ref() { + write!(f, "{}: {}", self.kind, source)?; + } else { + write!(f, "{}", self.kind)?; + } + Ok(()) + } +} diff --git a/typos/src/lib.rs b/typos/src/lib.rs index 1cb77c9..58ce818 100644 --- a/typos/src/lib.rs +++ b/typos/src/lib.rs @@ -1,7 +1,9 @@ mod dict; +mod error; pub mod checks; pub mod report; pub mod tokens; pub use crate::dict::*; +pub use crate::error::*; diff --git a/typos/src/tokens.rs b/typos/src/tokens.rs index 5617e98..c2c8c61 100644 --- a/typos/src/tokens.rs +++ b/typos/src/tokens.rs @@ -148,20 +148,23 @@ pub struct Word<'t> { } impl<'t> Word<'t> { - pub fn new(token: &'t str, offset: usize) -> Result { + pub fn new(token: &'t str, offset: usize) -> Result { let mut itr = split_ident(token, 0); - let mut item = itr - .next() - .ok_or_else(|| anyhow::anyhow!("Invalid word (none found): {:?}", token))?; + let mut item = itr.next().ok_or_else(|| { + crate::ErrorKind::InvalidWord + .into_error() + .with_message(format!("{:?} is nothing", token)) + })?; if item.offset != 0 { - return Err(anyhow::anyhow!("Invalid word (padding found): {:?}", token)); + return Err(crate::ErrorKind::InvalidWord + .into_error() + .with_message(format!("{:?} has padding", token))); } item.offset += offset; if itr.next().is_some() { - return Err(anyhow::anyhow!( - "Invalid word (contains more than one): {:?}", - token - )); + return Err(crate::ErrorKind::InvalidWord + .into_error() + .with_message(format!("{:?} is multiple words", token))); } Ok(item) }