mirror of
https://github.com/crate-ci/typos.git
synced 2024-12-22 23:52:12 -05:00
refactor(checks): Make all state dynamic
This commit is contained in:
parent
1c3acd747a
commit
ddeee94cf8
3 changed files with 66 additions and 125 deletions
|
@ -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,
|
||||
|
|
148
src/checks.rs
148
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<u8>, typos: impl Iterator<Item = typos::Typo<'stat
|
|||
pub fn walk_path(
|
||||
walk: ignore::Walk,
|
||||
checks: &dyn FileChecker,
|
||||
settings: &CheckSettings,
|
||||
parser: &typos::tokens::Tokenizer,
|
||||
dictionary: &dyn typos::Dictionary,
|
||||
reporter: &dyn report::Report,
|
||||
) -> 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<Result<(), ignore::Error>> = std::sync::Mutex::new(Ok(()));
|
||||
walk.run(|| {
|
||||
Box::new(|entry: Result<ignore::DirEntry, ignore::Error>| {
|
||||
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<ignore::DirEntry, ignore::Error>,
|
||||
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(())
|
||||
|
|
23
src/main.rs
23
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,
|
||||
|
|
Loading…
Reference in a new issue