Skip to content

Commit

Permalink
Merge pull request #174 from epage/pipe
Browse files Browse the repository at this point in the history
fix: Handle broken pipe
  • Loading branch information
epage authored Nov 22, 2020
2 parents d84117d + 869b916 commit 8ecffe7
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 340 deletions.
17 changes: 7 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ env_logger = "0.8"
bstr = "0.2"
ahash = "0.5.8"
difflib = "0.4"
sysexit = "0.2"
proc-exit = "0.1"

[dev-dependencies]
assert_fs = "1.0"
Expand Down
125 changes: 57 additions & 68 deletions crates/typos/src/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ pub trait Check: Send + Sync {
parser: &tokens::Parser,
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error>;
) -> Result<(), std::io::Error>;

fn check_bytes(
&self,
buffer: &[u8],
parser: &tokens::Parser,
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error>;
) -> Result<(), std::io::Error>;

fn check_filenames(&self) -> bool;

Expand All @@ -34,22 +34,20 @@ pub trait Check: Send + Sync {
parser: &tokens::Parser,
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let mut typos_found = false;

) -> Result<(), std::io::Error> {
if !self.check_filenames() {
return Ok(typos_found);
return Ok(());
}

if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) {
let context_reporter = ReportContext {
reporter,
context: report::PathContext { path }.into(),
};
typos_found |= self.check_str(file_name, parser, dictionary, &context_reporter)?;
self.check_str(file_name, parser, dictionary, &context_reporter)?;
}

Ok(typos_found)
Ok(())
}

fn check_file(
Expand All @@ -59,19 +57,17 @@ pub trait Check: Send + Sync {
parser: &tokens::Parser,
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let mut typos_found = false;

) -> Result<(), std::io::Error> {
if !self.check_files() {
return Ok(typos_found);
return Ok(());
}

let buffer = read_file(path)?;
let buffer = read_file(path, reporter)?;
let (buffer, content_type) = massage_data(buffer)?;
if !explicit && !self.binary() && content_type.is_binary() {
let msg = report::BinaryFile { path };
reporter.report(msg.into());
return Ok(typos_found);
reporter.report(msg.into())?;
return Ok(());
}

for (line_idx, line) in buffer.lines().enumerate() {
Expand All @@ -80,10 +76,10 @@ pub trait Check: Send + Sync {
reporter,
context: report::FileContext { path, line_num }.into(),
};
typos_found |= self.check_bytes(line, parser, dictionary, &context_reporter)?;
self.check_bytes(line, parser, dictionary, &context_reporter)?;
}

Ok(typos_found)
Ok(())
}
}

Expand All @@ -93,7 +89,7 @@ struct ReportContext<'m, 'r> {
}

impl<'m, 'r> report::Report for ReportContext<'m, 'r> {
fn report(&self, msg: report::Message) -> bool {
fn report(&self, msg: report::Message) -> Result<(), std::io::Error> {
let msg = msg.context(Some(self.context.clone()));
self.reporter.report(msg)
}
Expand Down Expand Up @@ -179,9 +175,7 @@ impl Check for Typos {
parser: &tokens::Parser,
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let mut typos_found = false;

) -> Result<(), std::io::Error> {
for ident in parser.parse_str(buffer) {
match dictionary.correct_ident(ident) {
Some(Status::Valid) => {}
Expand All @@ -194,7 +188,7 @@ impl Check for Typos {
typo: ident.token(),
corrections,
};
typos_found |= reporter.report(msg.into());
reporter.report(msg.into())?;
}
None => {
for word in ident.split() {
Expand All @@ -209,16 +203,15 @@ impl Check for Typos {
typo: word.token(),
corrections,
};
typos_found |= reporter.report(msg.into());
reporter.report(msg.into())?;
}
None => {}
}
}
}
}
}

Ok(typos_found)
Ok(())
}

fn check_bytes(
Expand All @@ -227,9 +220,7 @@ impl Check for Typos {
parser: &tokens::Parser,
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let mut typos_found = false;

) -> Result<(), std::io::Error> {
for ident in parser.parse_bytes(buffer) {
match dictionary.correct_ident(ident) {
Some(Status::Valid) => {}
Expand All @@ -242,7 +233,7 @@ impl Check for Typos {
typo: ident.token(),
corrections,
};
typos_found |= reporter.report(msg.into());
reporter.report(msg.into())?;
}
None => {
for word in ident.split() {
Expand All @@ -257,7 +248,7 @@ impl Check for Typos {
typo: word.token(),
corrections,
};
typos_found |= reporter.report(msg.into());
reporter.report(msg.into())?;
}
None => {}
}
Expand All @@ -266,7 +257,7 @@ impl Check for Typos {
}
}

Ok(typos_found)
Ok(())
}

fn check_filenames(&self) -> bool {
Expand Down Expand Up @@ -296,19 +287,17 @@ impl Check for ParseIdentifiers {
parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;

) -> Result<(), std::io::Error> {
let msg = report::Parse {
context: None,
kind: report::ParseKind::Identifier,
data: parser.parse_str(buffer).map(|i| i.token()).collect(),
};
if !msg.data.is_empty() {
reporter.report(msg.into());
reporter.report(msg.into())?;
}

Ok(typos_found)
Ok(())
}

fn check_bytes(
Expand All @@ -317,19 +306,17 @@ impl Check for ParseIdentifiers {
parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;

) -> Result<(), std::io::Error> {
let msg = report::Parse {
context: None,
kind: report::ParseKind::Identifier,
data: parser.parse_bytes(buffer).map(|i| i.token()).collect(),
};
if !msg.data.is_empty() {
reporter.report(msg.into());
reporter.report(msg.into())?;
}

Ok(typos_found)
Ok(())
}

fn check_filenames(&self) -> bool {
Expand Down Expand Up @@ -359,9 +346,7 @@ impl Check for ParseWords {
parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;

) -> Result<(), std::io::Error> {
let msg = report::Parse {
context: None,
kind: report::ParseKind::Word,
Expand All @@ -371,10 +356,10 @@ impl Check for ParseWords {
.collect(),
};
if !msg.data.is_empty() {
reporter.report(msg.into());
reporter.report(msg.into())?;
}

Ok(typos_found)
Ok(())
}

fn check_bytes(
Expand All @@ -383,9 +368,7 @@ impl Check for ParseWords {
parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;

) -> Result<(), std::io::Error> {
let msg = report::Parse {
context: None,
kind: report::ParseKind::Word,
Expand All @@ -395,10 +378,10 @@ impl Check for ParseWords {
.collect(),
};
if !msg.data.is_empty() {
reporter.report(msg.into());
reporter.report(msg.into())?;
}

Ok(typos_found)
Ok(())
}

fn check_filenames(&self) -> bool {
Expand All @@ -424,9 +407,8 @@ impl Check for Files {
_parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
_reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;
Ok(typos_found)
) -> Result<(), std::io::Error> {
Ok(())
}

fn check_bytes(
Expand All @@ -435,9 +417,8 @@ impl Check for Files {
_parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
_reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;
Ok(typos_found)
) -> Result<(), std::io::Error> {
Ok(())
}

fn check_filenames(&self) -> bool {
Expand All @@ -458,9 +439,8 @@ impl Check for Files {
_parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
_reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;
Ok(typos_found)
) -> Result<(), std::io::Error> {
Ok(())
}

fn check_file(
Expand All @@ -470,23 +450,32 @@ impl Check for Files {
_parser: &tokens::Parser,
_dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<bool, crate::Error> {
let typos_found = false;

) -> Result<(), std::io::Error> {
let msg = report::File::new(path);
reporter.report(msg.into());
reporter.report(msg.into())?;

Ok(typos_found)
Ok(())
}
}

fn read_file(path: &std::path::Path) -> Result<Vec<u8>, crate::Error> {
std::fs::read(path).map_err(|e| crate::ErrorKind::IoError.into_error().with_source(e))
fn read_file(
path: &std::path::Path,
reporter: &dyn report::Report,
) -> Result<Vec<u8>, std::io::Error> {
let buffer = match std::fs::read(path) {
Ok(buffer) => buffer,
Err(err) => {
let msg = report::Error::new(err.to_string());
reporter.report(msg.into())?;
Vec::new()
}
};
Ok(buffer)
}

fn massage_data(
buffer: Vec<u8>,
) -> Result<(Vec<u8>, content_inspector::ContentType), crate::Error> {
) -> Result<(Vec<u8>, content_inspector::ContentType), std::io::Error> {
let mut content_type = content_inspector::inspect(&buffer);

// HACK: We only support UTF-8 at the moment
Expand Down
Loading

0 comments on commit 8ecffe7

Please sign in to comment.