From 575971a5c5f17a3e76fadeacaaaf26d84e511636 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 23 Mar 2020 18:21:29 -0500 Subject: [PATCH] refactor: Turn reports into a trait --- benches/file.rs | 6 +- src/main.rs | 53 +++++++++------- typos/src/checks.rs | 34 +++++------ typos/src/report.rs | 146 +++++++++++++++++++++++++------------------- 4 files changed, 134 insertions(+), 105 deletions(-) diff --git a/benches/file.rs b/benches/file.rs index 2cc4395..183d79c 100644 --- a/benches/file.rs +++ b/benches/file.rs @@ -93,7 +93,7 @@ fn bench_parse_ident(data: &str, b: &mut test::Bencher) { sample_path.path(), true, &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(), true, &parser, - typos::report::print_silent, + &typos::report::PrintSilent, ) }); @@ -193,7 +193,7 @@ fn bench_check_file(data: &str, b: &mut test::Bencher) { true, &parser, &corrections, - typos::report::print_silent, + &typos::report::PrintSilent, ) }); diff --git a/src/main.rs b/src/main.rs index 65633f6..86c6f77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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 { - fn report(self) -> typos::report::Report { + fn reporter(self) -> &'static dyn typos::report::Report { match self { - Format::Silent => typos::report::print_silent, - Format::Brief => typos::report::print_brief, - Format::Long => typos::report::print_long, - Format::Json => typos::report::print_json, + Format::Silent => &PRINT_SILENT, + Format::Brief => &PRINT_BRIEF, + Format::Long => &PRINT_LONG, + Format::Json => &PRINT_JSON, } } } @@ -282,7 +287,7 @@ trait Checks: Send + Sync { path: &std::path::Path, parser: &typos::tokens::Parser, dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result; fn check_file( @@ -291,7 +296,7 @@ trait Checks: Send + Sync { explicit: bool, parser: &typos::tokens::Parser, dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result; } @@ -301,7 +306,7 @@ impl<'p> Checks for typos::checks::ParseIdentifiers { path: &std::path::Path, parser: &typos::tokens::Parser, _dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result { self.check_filename(path, parser, report) } @@ -312,7 +317,7 @@ impl<'p> Checks for typos::checks::ParseIdentifiers { explicit: bool, parser: &typos::tokens::Parser, _dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result { self.check_file(path, explicit, parser, report) } @@ -324,7 +329,7 @@ impl<'p> Checks for typos::checks::ParseWords { path: &std::path::Path, parser: &typos::tokens::Parser, _dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result { self.check_filename(path, parser, report) } @@ -335,7 +340,7 @@ impl<'p> Checks for typos::checks::ParseWords { explicit: bool, parser: &typos::tokens::Parser, _dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result { self.check_file(path, explicit, parser, report) } @@ -347,7 +352,7 @@ impl<'d, 'p> Checks for typos::checks::Checks { path: &std::path::Path, parser: &typos::tokens::Parser, dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result { self.check_filename(path, parser, dictionary, report) } @@ -358,7 +363,7 @@ impl<'d, 'p> Checks for typos::checks::Checks { explicit: bool, parser: &typos::tokens::Parser, dictionary: &dyn typos::Dictionary, - report: typos::report::Report, + report: &dyn typos::report::Report, ) -> Result { self.check_file(path, explicit, parser, dictionary, report) } @@ -402,7 +407,7 @@ fn check_path( Ok(true) => typos_found = true, Err(err) => { let msg = typos::report::Error::new(err.to_string()); - format.report()(msg.into()); + format.reporter().report(msg.into()); errors_found = true } _ => (), @@ -428,7 +433,7 @@ fn check_path_parallel( Ok(true) => typos_found.store(true, atomic::Ordering::Relaxed), Err(err) => { 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); } _ => (), @@ -452,10 +457,16 @@ fn check_entry( let entry = entry?; if entry.file_type().map(|t| t.is_file()).unwrap_or(true) { 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; } - 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; } } @@ -524,11 +535,11 @@ fn run() -> Result { match entry { Ok(entry) => { let msg = typos::report::File::new(entry.path()); - args.format.report()(msg.into()); + args.format.reporter().report(msg.into()); } Err(err) => { let msg = typos::report::Error::new(err.to_string()); - args.format.report()(msg.into()); + args.format.reporter().report(msg.into()); errors_found = true } } @@ -541,11 +552,11 @@ fn run() -> Result { match entry { Ok(entry) => { let msg = typos::report::File::new(entry.path()); - format.report()(msg.into()); + format.reporter().report(msg.into()); } Err(err) => { 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); } } diff --git a/typos/src/checks.rs b/typos/src/checks.rs index 3fdc149..2e6a611 100644 --- a/typos/src/checks.rs +++ b/typos/src/checks.rs @@ -78,7 +78,7 @@ impl ParseIdentifiers { &self, path: &std::path::Path, parser: &tokens::Parser, - report: report::Report, + reporter: &dyn report::Report, ) -> Result { let typos_found = false; @@ -93,7 +93,7 @@ impl ParseIdentifiers { data: parser.parse(part).map(|i| i.token()).collect(), non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); } Ok(typos_found) @@ -104,7 +104,7 @@ impl ParseIdentifiers { path: &std::path::Path, explicit: bool, parser: &tokens::Parser, - report: report::Report, + reporter: &dyn report::Report, ) -> Result { let typos_found = false; @@ -119,7 +119,7 @@ impl ParseIdentifiers { path, non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); return Ok(typos_found); } @@ -130,7 +130,7 @@ impl ParseIdentifiers { data: parser.parse_bytes(line).map(|i| i.token()).collect(), non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); } Ok(typos_found) @@ -149,7 +149,7 @@ impl ParseWords { &self, path: &std::path::Path, parser: &tokens::Parser, - report: report::Report, + reporter: &dyn report::Report, ) -> Result { let typos_found = false; @@ -167,7 +167,7 @@ impl ParseWords { .collect(), non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); } Ok(typos_found) @@ -178,7 +178,7 @@ impl ParseWords { path: &std::path::Path, explicit: bool, parser: &tokens::Parser, - report: report::Report, + reporter: &dyn report::Report, ) -> Result { let typos_found = false; @@ -193,7 +193,7 @@ impl ParseWords { path, non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); return Ok(typos_found); } @@ -207,7 +207,7 @@ impl ParseWords { .collect(), non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); } Ok(typos_found) @@ -227,7 +227,7 @@ impl Checks { path: &std::path::Path, parser: &tokens::Parser, dictionary: &dyn Dictionary, - report: report::Report, + reporter: &dyn report::Report, ) -> Result { let mut typos_found = false; @@ -244,7 +244,7 @@ impl Checks { correction, non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); typos_found = true; } else { for word in ident.split() { @@ -255,7 +255,7 @@ impl Checks { correction, non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); typos_found = true; } } @@ -272,7 +272,7 @@ impl Checks { explicit: bool, parser: &tokens::Parser, dictionary: &dyn Dictionary, - report: report::Report, + reporter: &dyn report::Report, ) -> Result { let mut typos_found = false; @@ -287,7 +287,7 @@ impl Checks { path, non_exhaustive: (), }; - report(msg.into()); + reporter.report(msg.into()); return Ok(typos_found); } @@ -306,7 +306,7 @@ impl Checks { non_exhaustive: (), }; typos_found = true; - report(msg.into()); + reporter.report(msg.into()); } else { for word in ident.split() { if let Some(correction) = dictionary.correct_word(word) { @@ -321,7 +321,7 @@ impl Checks { non_exhaustive: (), }; typos_found = true; - report(msg.into()); + reporter.report(msg.into()); } } } diff --git a/typos/src/report.rs b/typos/src/report.rs index 451e445..ac0d435 100644 --- a/typos/src/report.rs +++ b/typos/src/report.rs @@ -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) { - match msg { - Message::BinaryFile(msg) => { - println!("{}", msg); - } - Message::Correction(msg) => { - println!( - "{}:{}:{}: {} -> {}", - msg.path.display(), - msg.line_num, - msg.col_num, - msg.typo, - msg.correction - ); - } - Message::FilenameCorrection(msg) => { - println!("{}: {} -> {}", msg.path.display(), msg.typo, msg.correction); - } - Message::File(msg) => { - println!("{}", msg.path.display()); - } - Message::Parse(msg) => { - println!("{}", itertools::join(msg.data.iter(), " ")); - } - Message::PathError(msg) => { - println!("{}: {}", msg.path.display(), msg.msg); - } - Message::Error(msg) => { - println!("{}", msg.msg); - } - Message::__NonExhaustive => { - unreachable!("Non-creatable case"); +impl Report for PrintSilent { + fn report(&self, _msg: Message) {} +} + +pub struct PrintBrief; + +impl Report for PrintBrief { + fn report(&self, msg: Message) { + match msg { + Message::BinaryFile(msg) => { + println!("{}", msg); + } + Message::Correction(msg) => { + println!( + "{}:{}:{}: {} -> {}", + msg.path.display(), + msg.line_num, + msg.col_num, + msg.typo, + msg.correction + ); + } + Message::FilenameCorrection(msg) => { + println!("{}: {} -> {}", msg.path.display(), msg.typo, msg.correction); + } + Message::File(msg) => { + println!("{}", msg.path.display()); + } + Message::Parse(msg) => { + println!("{}", itertools::join(msg.data.iter(), " ")); + } + 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) { - match msg { - Message::BinaryFile(msg) => { - println!("{}", msg); - } - Message::Correction(msg) => print_long_correction(msg), - Message::FilenameCorrection(msg) => { - println!( - "{}: error: `{}` should be `{}`", - msg.path.display(), - msg.typo, - msg.correction - ); - } - Message::File(msg) => { - println!("{}", msg.path.display()); - } - Message::Parse(msg) => { - println!("{}", itertools::join(msg.data.iter(), " ")); - } - Message::PathError(msg) => { - println!("{}: {}", msg.path.display(), msg.msg); - } - Message::Error(msg) => { - println!("{}", msg.msg); - } - Message::__NonExhaustive => { - unreachable!("Non-creatable case"); +pub struct PrintLong; + +impl Report for PrintLong { + fn report(&self, msg: Message) { + match msg { + Message::BinaryFile(msg) => { + println!("{}", msg); + } + Message::Correction(msg) => print_long_correction(msg), + Message::FilenameCorrection(msg) => { + println!( + "{}: error: `{}` should be `{}`", + msg.path.display(), + msg.typo, + msg.correction + ); + } + Message::File(msg) => { + println!("{}", msg.path.display()); + } + Message::Parse(msg) => { + println!("{}", itertools::join(msg.data.iter(), " ")); + } + Message::PathError(msg) => { + println!("{}: {}", msg.path.display(), msg.msg); + } + Message::Error(msg) => { + println!("{}", msg.msg); + } + Message::__NonExhaustive => { + unreachable!("Non-creatable case"); + } } } } @@ -208,6 +222,10 @@ fn print_long_correction(msg: Correction) { writeln!(handle, "{} |", line_indent).unwrap(); } -pub fn print_json(msg: Message) { - println!("{}", serde_json::to_string(&msg).unwrap()); +pub struct PrintJson; + +impl Report for PrintJson { + fn report(&self, msg: Message) { + println!("{}", serde_json::to_string(&msg).unwrap()); + } }