From ddeee94cf83ed554699b0451fda5ce5d047bd153 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 5 Jan 2021 21:29:33 -0600 Subject: [PATCH] refactor(checks): Make all state dynamic --- benches/checks.rs | 20 ++++--- src/checks.rs | 148 ++++++++++++++-------------------------------- src/main.rs | 23 +++---- 3 files changed, 66 insertions(+), 125 deletions(-) diff --git a/benches/checks.rs b/benches/checks.rs index 2b311e8..1877d72 100644 --- a/benches/checks.rs +++ b/benches/checks.rs @@ -15,11 +15,12 @@ fn bench_checks(c: &mut Criterion) { let corrections = typos_cli::dict::BuiltIn::new(Default::default()); let parser = typos::tokens::Tokenizer::new(); - let checks = typos_cli::checks::TyposSettings::new().build_files(); + let settings = typos_cli::checks::CheckSettings::new(); b.iter(|| { - checks.check_file( + typos_cli::checks::FoundFiles.check_file( sample_path.path(), true, + &settings, &parser, &corrections, &typos_cli::report::PrintSilent, @@ -35,11 +36,12 @@ fn bench_checks(c: &mut Criterion) { let corrections = typos_cli::dict::BuiltIn::new(Default::default()); let parser = typos::tokens::Tokenizer::new(); - let checks = typos_cli::checks::TyposSettings::new().build_identifier_parser(); + let settings = typos_cli::checks::CheckSettings::new(); b.iter(|| { - checks.check_file( + typos_cli::checks::Identifiers.check_file( sample_path.path(), true, + &settings, &parser, &corrections, &typos_cli::report::PrintSilent, @@ -55,11 +57,12 @@ fn bench_checks(c: &mut Criterion) { let corrections = typos_cli::dict::BuiltIn::new(Default::default()); let parser = typos::tokens::Tokenizer::new(); - let checks = typos_cli::checks::TyposSettings::new().build_word_parser(); + let settings = typos_cli::checks::CheckSettings::new(); b.iter(|| { - checks.check_file( + typos_cli::checks::Words.check_file( sample_path.path(), true, + &settings, &parser, &corrections, &typos_cli::report::PrintSilent, @@ -75,11 +78,12 @@ fn bench_checks(c: &mut Criterion) { let corrections = typos_cli::dict::BuiltIn::new(Default::default()); let parser = typos::tokens::Tokenizer::new(); - let checks = typos_cli::checks::TyposSettings::new().build_typos(); + let settings = typos_cli::checks::CheckSettings::new(); b.iter(|| { - checks.check_file( + typos_cli::checks::Typos.check_file( sample_path.path(), true, + &settings, &parser, &corrections, &typos_cli::report::PrintSilent, diff --git a/src/checks.rs b/src/checks.rs index 81abcd8..7b19181 100644 --- a/src/checks.rs +++ b/src/checks.rs @@ -12,6 +12,7 @@ pub trait FileChecker: Send + Sync { &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, parser: &tokens::Tokenizer, dictionary: &dyn Dictionary, reporter: &dyn report::Report, @@ -19,13 +20,13 @@ pub trait FileChecker: Send + Sync { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct TyposSettings { +pub struct CheckSettings { check_filenames: bool, check_files: bool, binary: bool, } -impl TyposSettings { +impl CheckSettings { pub fn new() -> Self { Default::default() } @@ -44,55 +45,9 @@ impl TyposSettings { self.binary = yes; self } - - pub fn build_typos(&self) -> Typos { - Typos { - check_filenames: self.check_filenames, - check_files: self.check_files, - binary: self.binary, - } - } - - pub fn build_fix_typos(&self) -> FixTypos { - FixTypos { - check_filenames: self.check_filenames, - check_files: self.check_files, - binary: self.binary, - } - } - - pub fn build_diff_typos(&self) -> DiffTypos { - DiffTypos { - check_filenames: self.check_filenames, - check_files: self.check_files, - binary: self.binary, - } - } - - pub fn build_identifier_parser(&self) -> Identifiers { - Identifiers { - check_filenames: self.check_filenames, - check_files: self.check_files, - binary: self.binary, - } - } - - pub fn build_word_parser(&self) -> Words { - Words { - check_filenames: self.check_filenames, - check_files: self.check_files, - binary: self.binary, - } - } - - pub fn build_files(&self) -> FoundFiles { - FoundFiles { - binary: self.binary, - } - } } -impl Default for TyposSettings { +impl Default for CheckSettings { fn default() -> Self { Self { check_filenames: true, @@ -102,18 +57,15 @@ impl Default for TyposSettings { } } -#[derive(Debug, Clone)] -pub struct Typos { - check_filenames: bool, - check_files: bool, - binary: bool, -} +#[derive(Debug, Clone, Copy)] +pub struct Typos; impl FileChecker for Typos { fn check_file( &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, tokenizer: &tokens::Tokenizer, dictionary: &dyn Dictionary, reporter: &dyn report::Report, @@ -123,7 +75,7 @@ impl FileChecker for Typos { .dictionary(dictionary) .build(); - if self.check_filenames { + if settings.check_filenames { if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) { for typo in parser.parse_str(file_name) { let msg = report::Typo { @@ -138,9 +90,9 @@ impl FileChecker for Typos { } } - if self.check_files { + if settings.check_files { let (buffer, content_type) = read_file(path, reporter)?; - if !explicit && !self.binary && content_type.is_binary() { + if !explicit && !settings.binary && content_type.is_binary() { let msg = report::BinaryFile { path }; reporter.report(msg.into())?; } else { @@ -164,18 +116,15 @@ impl FileChecker for Typos { } } -#[derive(Debug, Clone)] -pub struct FixTypos { - check_filenames: bool, - check_files: bool, - binary: bool, -} +#[derive(Debug, Clone, Copy)] +pub struct FixTypos; impl FileChecker for FixTypos { fn check_file( &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, tokenizer: &tokens::Tokenizer, dictionary: &dyn Dictionary, reporter: &dyn report::Report, @@ -185,9 +134,9 @@ impl FileChecker for FixTypos { .dictionary(dictionary) .build(); - if self.check_files { + if settings.check_files { let (buffer, content_type) = read_file(path, reporter)?; - if !explicit && !self.binary && content_type.is_binary() { + if !explicit && !settings.binary && content_type.is_binary() { let msg = report::BinaryFile { path }; reporter.report(msg.into())?; } else { @@ -217,7 +166,7 @@ impl FileChecker for FixTypos { } // Ensure the above write can happen before renaming the file. - if self.check_filenames { + if settings.check_filenames { if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) { let mut fixes = Vec::new(); for typo in parser.parse_str(file_name) { @@ -249,18 +198,15 @@ impl FileChecker for FixTypos { } } -#[derive(Debug, Clone)] -pub struct DiffTypos { - check_filenames: bool, - check_files: bool, - binary: bool, -} +#[derive(Debug, Clone, Copy)] +pub struct DiffTypos; impl FileChecker for DiffTypos { fn check_file( &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, tokenizer: &tokens::Tokenizer, dictionary: &dyn Dictionary, reporter: &dyn report::Report, @@ -272,9 +218,9 @@ impl FileChecker for DiffTypos { let mut content = Vec::new(); let mut new_content = Vec::new(); - if self.check_files { + if settings.check_files { let (buffer, content_type) = read_file(path, reporter)?; - if !explicit && !self.binary && content_type.is_binary() { + if !explicit && !settings.binary && content_type.is_binary() { let msg = report::BinaryFile { path }; reporter.report(msg.into())?; } else { @@ -305,7 +251,7 @@ impl FileChecker for DiffTypos { // Match FixTypos ordering for easy diffing. let mut new_path = None; - if self.check_filenames { + if settings.check_filenames { if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) { let mut fixes = Vec::new(); for typo in parser.parse_str(file_name) { @@ -361,23 +307,20 @@ impl FileChecker for DiffTypos { } } -#[derive(Debug, Clone)] -pub struct Identifiers { - check_filenames: bool, - check_files: bool, - binary: bool, -} +#[derive(Debug, Clone, Copy)] +pub struct Identifiers; impl FileChecker for Identifiers { fn check_file( &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, tokenizer: &tokens::Tokenizer, _dictionary: &dyn Dictionary, reporter: &dyn report::Report, ) -> Result<(), std::io::Error> { - if self.check_filenames { + if settings.check_filenames { if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) { for word in tokenizer.parse_str(file_name) { let msg = report::Parse { @@ -390,9 +333,9 @@ impl FileChecker for Identifiers { } } - if self.check_files { + if settings.check_files { let (buffer, content_type) = read_file(path, reporter)?; - if !explicit && !self.binary && content_type.is_binary() { + if !explicit && !settings.binary && content_type.is_binary() { let msg = report::BinaryFile { path }; reporter.report(msg.into())?; } else { @@ -415,23 +358,20 @@ impl FileChecker for Identifiers { } } -#[derive(Debug, Clone)] -pub struct Words { - check_filenames: bool, - check_files: bool, - binary: bool, -} +#[derive(Debug, Clone, Copy)] +pub struct Words; impl FileChecker for Words { fn check_file( &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, tokenizer: &tokens::Tokenizer, _dictionary: &dyn Dictionary, reporter: &dyn report::Report, ) -> Result<(), std::io::Error> { - if self.check_filenames { + if settings.check_filenames { if let Some(file_name) = path.file_name().and_then(|s| s.to_str()) { for word in tokenizer.parse_str(file_name).flat_map(|i| i.split()) { let msg = report::Parse { @@ -444,9 +384,9 @@ impl FileChecker for Words { } } - if self.check_files { + if settings.check_files { let (buffer, content_type) = read_file(path, reporter)?; - if !explicit && !self.binary && content_type.is_binary() { + if !explicit && !settings.binary && content_type.is_binary() { let msg = report::BinaryFile { path }; reporter.report(msg.into())?; } else { @@ -469,22 +409,21 @@ impl FileChecker for Words { } } -#[derive(Debug, Clone)] -pub struct FoundFiles { - binary: bool, -} +#[derive(Debug, Clone, Copy)] +pub struct FoundFiles; impl FileChecker for FoundFiles { fn check_file( &self, path: &std::path::Path, explicit: bool, + settings: &CheckSettings, _parser: &tokens::Tokenizer, _dictionary: &dyn Dictionary, reporter: &dyn report::Report, ) -> Result<(), std::io::Error> { - // Check `self.binary` first so we can easily check performance of walking vs reading - if self.binary { + // Check `settings.binary` first so we can easily check performance of walking vs reading + if settings.binary { let msg = report::File::new(path); reporter.report(msg.into())?; } else { @@ -674,12 +613,13 @@ fn fix_buffer(mut buffer: Vec, typos: impl Iterator Result<(), ignore::Error> { for entry in walk { - walk_entry(entry, checks, parser, dictionary, reporter)?; + walk_entry(entry, checks, settings, parser, dictionary, reporter)?; } Ok(()) } @@ -687,6 +627,7 @@ pub fn walk_path( pub fn walk_path_parallel( walk: ignore::WalkParallel, checks: &dyn FileChecker, + settings: &CheckSettings, parser: &typos::tokens::Tokenizer, dictionary: &dyn typos::Dictionary, reporter: &dyn report::Report, @@ -694,7 +635,7 @@ pub fn walk_path_parallel( let error: std::sync::Mutex> = std::sync::Mutex::new(Ok(())); walk.run(|| { Box::new(|entry: Result| { - match walk_entry(entry, checks, parser, dictionary, reporter) { + match walk_entry(entry, checks, settings, parser, dictionary, reporter) { Ok(()) => ignore::WalkState::Continue, Err(err) => { *error.lock().unwrap() = Err(err); @@ -710,6 +651,7 @@ pub fn walk_path_parallel( fn walk_entry( entry: Result, checks: &dyn FileChecker, + settings: &CheckSettings, parser: &typos::tokens::Tokenizer, dictionary: &dyn typos::Dictionary, reporter: &dyn report::Report, @@ -728,7 +670,7 @@ fn walk_entry( } else { entry.path() }; - checks.check_file(path, explicit, parser, dictionary, reporter)?; + checks.check_file(path, explicit, settings, parser, dictionary, reporter)?; } Ok(()) diff --git a/src/main.rs b/src/main.rs index 30eb5ae..5272176 100644 --- a/src/main.rs +++ b/src/main.rs @@ -105,7 +105,7 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult { dictionary.identifiers(config.default.extend_identifiers()); dictionary.words(config.default.extend_words()); - let mut settings = checks::TyposSettings::new(); + let mut settings = checks::CheckSettings::new(); settings .check_filenames(config.default.check_filename()) .check_files(config.default.check_file()) @@ -132,31 +132,25 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult { let status_reporter = report::MessageStatus::new(output_reporter); let reporter: &dyn report::Report = &status_reporter; - let (files, identifier_parser, word_parser, checks, fixer, differ); let selected_checks: &dyn checks::FileChecker = if args.files { - files = settings.build_files(); - &files + &checks::FoundFiles } else if args.identifiers { - identifier_parser = settings.build_identifier_parser(); - &identifier_parser + &checks::Identifiers } else if args.words { - word_parser = settings.build_word_parser(); - &word_parser + &checks::Words } else if args.write_changes { - fixer = settings.build_fix_typos(); - &fixer + &checks::FixTypos } else if args.diff { - differ = settings.build_diff_typos(); - &differ + &checks::DiffTypos } else { - checks = settings.build_typos(); - &checks + &checks::Typos }; if single_threaded { checks::walk_path( walk.build(), selected_checks, + &settings, &parser, &dictionary, reporter, @@ -165,6 +159,7 @@ fn run_checks(args: &args::Args) -> proc_exit::ExitResult { checks::walk_path_parallel( walk.build_parallel(), selected_checks, + &settings, &parser, &dictionary, reporter,