refactor: Turn reports into a trait

This commit is contained in:
Ed Page 2020-03-23 18:21:29 -05:00 committed by Ed Page
parent 3ae9c2ab52
commit 575971a5c5
4 changed files with 134 additions and 105 deletions

View file

@ -93,7 +93,7 @@ fn bench_parse_ident(data: &str, b: &mut test::Bencher) {
sample_path.path(), sample_path.path(),
true, true,
&parser, &parser,
typos::report::print_silent, &typos::report::PrintSilent,
) )
}); });
@ -142,7 +142,7 @@ fn bench_parse_word(data: &str, b: &mut test::Bencher) {
sample_path.path(), sample_path.path(),
true, true,
&parser, &parser,
typos::report::print_silent, &typos::report::PrintSilent,
) )
}); });
@ -193,7 +193,7 @@ fn bench_check_file(data: &str, b: &mut test::Bencher) {
true, true,
&parser, &parser,
&corrections, &corrections,
typos::report::print_silent, &typos::report::PrintSilent,
) )
}); });

View file

@ -20,13 +20,18 @@ arg_enum! {
} }
} }
const PRINT_SILENT: typos::report::PrintSilent = typos::report::PrintSilent;
const PRINT_BRIEF: typos::report::PrintBrief = typos::report::PrintBrief;
const PRINT_LONG: typos::report::PrintLong = typos::report::PrintLong;
const PRINT_JSON: typos::report::PrintJson = typos::report::PrintJson;
impl Format { impl Format {
fn report(self) -> typos::report::Report { fn reporter(self) -> &'static dyn typos::report::Report {
match self { match self {
Format::Silent => typos::report::print_silent, Format::Silent => &PRINT_SILENT,
Format::Brief => typos::report::print_brief, Format::Brief => &PRINT_BRIEF,
Format::Long => typos::report::print_long, Format::Long => &PRINT_LONG,
Format::Json => typos::report::print_json, Format::Json => &PRINT_JSON,
} }
} }
} }
@ -282,7 +287,7 @@ trait Checks: Send + Sync {
path: &std::path::Path, path: &std::path::Path,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
dictionary: &dyn typos::Dictionary, dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error>; ) -> Result<bool, typos::Error>;
fn check_file( fn check_file(
@ -291,7 +296,7 @@ trait Checks: Send + Sync {
explicit: bool, explicit: bool,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
dictionary: &dyn typos::Dictionary, dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error>; ) -> Result<bool, typos::Error>;
} }
@ -301,7 +306,7 @@ impl<'p> Checks for typos::checks::ParseIdentifiers {
path: &std::path::Path, path: &std::path::Path,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
_dictionary: &dyn typos::Dictionary, _dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error> { ) -> Result<bool, typos::Error> {
self.check_filename(path, parser, report) self.check_filename(path, parser, report)
} }
@ -312,7 +317,7 @@ impl<'p> Checks for typos::checks::ParseIdentifiers {
explicit: bool, explicit: bool,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
_dictionary: &dyn typos::Dictionary, _dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error> { ) -> Result<bool, typos::Error> {
self.check_file(path, explicit, parser, report) self.check_file(path, explicit, parser, report)
} }
@ -324,7 +329,7 @@ impl<'p> Checks for typos::checks::ParseWords {
path: &std::path::Path, path: &std::path::Path,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
_dictionary: &dyn typos::Dictionary, _dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error> { ) -> Result<bool, typos::Error> {
self.check_filename(path, parser, report) self.check_filename(path, parser, report)
} }
@ -335,7 +340,7 @@ impl<'p> Checks for typos::checks::ParseWords {
explicit: bool, explicit: bool,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
_dictionary: &dyn typos::Dictionary, _dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error> { ) -> Result<bool, typos::Error> {
self.check_file(path, explicit, parser, report) self.check_file(path, explicit, parser, report)
} }
@ -347,7 +352,7 @@ impl<'d, 'p> Checks for typos::checks::Checks {
path: &std::path::Path, path: &std::path::Path,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
dictionary: &dyn typos::Dictionary, dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error> { ) -> Result<bool, typos::Error> {
self.check_filename(path, parser, dictionary, report) self.check_filename(path, parser, dictionary, report)
} }
@ -358,7 +363,7 @@ impl<'d, 'p> Checks for typos::checks::Checks {
explicit: bool, explicit: bool,
parser: &typos::tokens::Parser, parser: &typos::tokens::Parser,
dictionary: &dyn typos::Dictionary, dictionary: &dyn typos::Dictionary,
report: typos::report::Report, report: &dyn typos::report::Report,
) -> Result<bool, typos::Error> { ) -> Result<bool, typos::Error> {
self.check_file(path, explicit, parser, dictionary, report) self.check_file(path, explicit, parser, dictionary, report)
} }
@ -402,7 +407,7 @@ fn check_path(
Ok(true) => typos_found = true, Ok(true) => typos_found = true,
Err(err) => { Err(err) => {
let msg = typos::report::Error::new(err.to_string()); let msg = typos::report::Error::new(err.to_string());
format.report()(msg.into()); format.reporter().report(msg.into());
errors_found = true errors_found = true
} }
_ => (), _ => (),
@ -428,7 +433,7 @@ fn check_path_parallel(
Ok(true) => typos_found.store(true, atomic::Ordering::Relaxed), Ok(true) => typos_found.store(true, atomic::Ordering::Relaxed),
Err(err) => { Err(err) => {
let msg = typos::report::Error::new(err.to_string()); let msg = typos::report::Error::new(err.to_string());
format.report()(msg.into()); format.reporter().report(msg.into());
errors_found.store(true, atomic::Ordering::Relaxed); errors_found.store(true, atomic::Ordering::Relaxed);
} }
_ => (), _ => (),
@ -452,10 +457,16 @@ fn check_entry(
let entry = entry?; let entry = entry?;
if entry.file_type().map(|t| t.is_file()).unwrap_or(true) { if entry.file_type().map(|t| t.is_file()).unwrap_or(true) {
let explicit = entry.depth() == 0; let explicit = entry.depth() == 0;
if checks.check_filename(entry.path(), parser, dictionary, format.report())? { if checks.check_filename(entry.path(), parser, dictionary, format.reporter())? {
typos_found = true; typos_found = true;
} }
if checks.check_file(entry.path(), explicit, parser, dictionary, format.report())? { if checks.check_file(
entry.path(),
explicit,
parser,
dictionary,
format.reporter(),
)? {
typos_found = true; typos_found = true;
} }
} }
@ -524,11 +535,11 @@ fn run() -> Result<i32, anyhow::Error> {
match entry { match entry {
Ok(entry) => { Ok(entry) => {
let msg = typos::report::File::new(entry.path()); let msg = typos::report::File::new(entry.path());
args.format.report()(msg.into()); args.format.reporter().report(msg.into());
} }
Err(err) => { Err(err) => {
let msg = typos::report::Error::new(err.to_string()); let msg = typos::report::Error::new(err.to_string());
args.format.report()(msg.into()); args.format.reporter().report(msg.into());
errors_found = true errors_found = true
} }
} }
@ -541,11 +552,11 @@ fn run() -> Result<i32, anyhow::Error> {
match entry { match entry {
Ok(entry) => { Ok(entry) => {
let msg = typos::report::File::new(entry.path()); let msg = typos::report::File::new(entry.path());
format.report()(msg.into()); format.reporter().report(msg.into());
} }
Err(err) => { Err(err) => {
let msg = typos::report::Error::new(err.to_string()); let msg = typos::report::Error::new(err.to_string());
format.report()(msg.into()); format.reporter().report(msg.into());
atomic_errors.store(true, atomic::Ordering::Relaxed); atomic_errors.store(true, atomic::Ordering::Relaxed);
} }
} }

View file

@ -78,7 +78,7 @@ impl ParseIdentifiers {
&self, &self,
path: &std::path::Path, path: &std::path::Path,
parser: &tokens::Parser, parser: &tokens::Parser,
report: report::Report, reporter: &dyn report::Report,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let typos_found = false; let typos_found = false;
@ -93,7 +93,7 @@ impl ParseIdentifiers {
data: parser.parse(part).map(|i| i.token()).collect(), data: parser.parse(part).map(|i| i.token()).collect(),
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
} }
Ok(typos_found) Ok(typos_found)
@ -104,7 +104,7 @@ impl ParseIdentifiers {
path: &std::path::Path, path: &std::path::Path,
explicit: bool, explicit: bool,
parser: &tokens::Parser, parser: &tokens::Parser,
report: report::Report, reporter: &dyn report::Report,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let typos_found = false; let typos_found = false;
@ -119,7 +119,7 @@ impl ParseIdentifiers {
path, path,
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
return Ok(typos_found); return Ok(typos_found);
} }
@ -130,7 +130,7 @@ impl ParseIdentifiers {
data: parser.parse_bytes(line).map(|i| i.token()).collect(), data: parser.parse_bytes(line).map(|i| i.token()).collect(),
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
} }
Ok(typos_found) Ok(typos_found)
@ -149,7 +149,7 @@ impl ParseWords {
&self, &self,
path: &std::path::Path, path: &std::path::Path,
parser: &tokens::Parser, parser: &tokens::Parser,
report: report::Report, reporter: &dyn report::Report,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let typos_found = false; let typos_found = false;
@ -167,7 +167,7 @@ impl ParseWords {
.collect(), .collect(),
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
} }
Ok(typos_found) Ok(typos_found)
@ -178,7 +178,7 @@ impl ParseWords {
path: &std::path::Path, path: &std::path::Path,
explicit: bool, explicit: bool,
parser: &tokens::Parser, parser: &tokens::Parser,
report: report::Report, reporter: &dyn report::Report,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let typos_found = false; let typos_found = false;
@ -193,7 +193,7 @@ impl ParseWords {
path, path,
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
return Ok(typos_found); return Ok(typos_found);
} }
@ -207,7 +207,7 @@ impl ParseWords {
.collect(), .collect(),
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
} }
Ok(typos_found) Ok(typos_found)
@ -227,7 +227,7 @@ impl Checks {
path: &std::path::Path, path: &std::path::Path,
parser: &tokens::Parser, parser: &tokens::Parser,
dictionary: &dyn Dictionary, dictionary: &dyn Dictionary,
report: report::Report, reporter: &dyn report::Report,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let mut typos_found = false; let mut typos_found = false;
@ -244,7 +244,7 @@ impl Checks {
correction, correction,
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
typos_found = true; typos_found = true;
} else { } else {
for word in ident.split() { for word in ident.split() {
@ -255,7 +255,7 @@ impl Checks {
correction, correction,
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
typos_found = true; typos_found = true;
} }
} }
@ -272,7 +272,7 @@ impl Checks {
explicit: bool, explicit: bool,
parser: &tokens::Parser, parser: &tokens::Parser,
dictionary: &dyn Dictionary, dictionary: &dyn Dictionary,
report: report::Report, reporter: &dyn report::Report,
) -> Result<bool, crate::Error> { ) -> Result<bool, crate::Error> {
let mut typos_found = false; let mut typos_found = false;
@ -287,7 +287,7 @@ impl Checks {
path, path,
non_exhaustive: (), non_exhaustive: (),
}; };
report(msg.into()); reporter.report(msg.into());
return Ok(typos_found); return Ok(typos_found);
} }
@ -306,7 +306,7 @@ impl Checks {
non_exhaustive: (), non_exhaustive: (),
}; };
typos_found = true; typos_found = true;
report(msg.into()); reporter.report(msg.into());
} else { } else {
for word in ident.split() { for word in ident.split() {
if let Some(correction) = dictionary.correct_word(word) { if let Some(correction) = dictionary.correct_word(word) {
@ -321,7 +321,7 @@ impl Checks {
non_exhaustive: (), non_exhaustive: (),
}; };
typos_found = true; typos_found = true;
report(msg.into()); reporter.report(msg.into());
} }
} }
} }

View file

@ -103,74 +103,88 @@ impl Error {
} }
} }
pub type Report = fn(msg: Message); pub trait Report: Send + Sync {
fn report(&self, msg: Message);
}
pub fn print_silent(_: Message) {} pub struct PrintSilent;
pub fn print_brief(msg: Message) { impl Report for PrintSilent {
match msg { fn report(&self, _msg: Message) {}
Message::BinaryFile(msg) => { }
println!("{}", msg);
} pub struct PrintBrief;
Message::Correction(msg) => {
println!( impl Report for PrintBrief {
"{}:{}:{}: {} -> {}", fn report(&self, msg: Message) {
msg.path.display(), match msg {
msg.line_num, Message::BinaryFile(msg) => {
msg.col_num, println!("{}", msg);
msg.typo, }
msg.correction Message::Correction(msg) => {
); println!(
} "{}:{}:{}: {} -> {}",
Message::FilenameCorrection(msg) => { msg.path.display(),
println!("{}: {} -> {}", msg.path.display(), msg.typo, msg.correction); msg.line_num,
} msg.col_num,
Message::File(msg) => { msg.typo,
println!("{}", msg.path.display()); msg.correction
} );
Message::Parse(msg) => { }
println!("{}", itertools::join(msg.data.iter(), " ")); Message::FilenameCorrection(msg) => {
} println!("{}: {} -> {}", msg.path.display(), msg.typo, msg.correction);
Message::PathError(msg) => { }
println!("{}: {}", msg.path.display(), msg.msg); Message::File(msg) => {
} println!("{}", msg.path.display());
Message::Error(msg) => { }
println!("{}", msg.msg); Message::Parse(msg) => {
} println!("{}", itertools::join(msg.data.iter(), " "));
Message::__NonExhaustive => { }
unreachable!("Non-creatable case"); Message::PathError(msg) => {
println!("{}: {}", msg.path.display(), msg.msg);
}
Message::Error(msg) => {
println!("{}", msg.msg);
}
Message::__NonExhaustive => {
unreachable!("Non-creatable case");
}
} }
} }
} }
pub fn print_long(msg: Message) { pub struct PrintLong;
match msg {
Message::BinaryFile(msg) => { impl Report for PrintLong {
println!("{}", msg); fn report(&self, msg: Message) {
} match msg {
Message::Correction(msg) => print_long_correction(msg), Message::BinaryFile(msg) => {
Message::FilenameCorrection(msg) => { println!("{}", msg);
println!( }
"{}: error: `{}` should be `{}`", Message::Correction(msg) => print_long_correction(msg),
msg.path.display(), Message::FilenameCorrection(msg) => {
msg.typo, println!(
msg.correction "{}: error: `{}` should be `{}`",
); msg.path.display(),
} msg.typo,
Message::File(msg) => { msg.correction
println!("{}", msg.path.display()); );
} }
Message::Parse(msg) => { Message::File(msg) => {
println!("{}", itertools::join(msg.data.iter(), " ")); println!("{}", msg.path.display());
} }
Message::PathError(msg) => { Message::Parse(msg) => {
println!("{}: {}", msg.path.display(), msg.msg); println!("{}", itertools::join(msg.data.iter(), " "));
} }
Message::Error(msg) => { Message::PathError(msg) => {
println!("{}", msg.msg); println!("{}: {}", msg.path.display(), msg.msg);
} }
Message::__NonExhaustive => { Message::Error(msg) => {
unreachable!("Non-creatable case"); println!("{}", msg.msg);
}
Message::__NonExhaustive => {
unreachable!("Non-creatable case");
}
} }
} }
} }
@ -208,6 +222,10 @@ fn print_long_correction(msg: Correction) {
writeln!(handle, "{} |", line_indent).unwrap(); writeln!(handle, "{} |", line_indent).unwrap();
} }
pub fn print_json(msg: Message) { pub struct PrintJson;
println!("{}", serde_json::to_string(&msg).unwrap());
impl Report for PrintJson {
fn report(&self, msg: Message) {
println!("{}", serde_json::to_string(&msg).unwrap());
}
} }