Skip to content

Commit

Permalink
refactor(typos): Simplify the top-level API
Browse files Browse the repository at this point in the history
  • Loading branch information
Ed Page committed Mar 1, 2021
1 parent e1e4ce8 commit b5f606f
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 185 deletions.
100 changes: 100 additions & 0 deletions crates/typos/src/check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use crate::tokens;
use crate::Dictionary;
use std::borrow::Cow;

pub fn check_str<'b, 's: 'b>(
buffer: &'b str,
tokenizer: &'s tokens::Tokenizer,
dictionary: &'s dyn Dictionary,
) -> impl Iterator<Item = Typo<'b>> {
tokenizer
.parse_str(buffer)
.flat_map(move |ident| process_ident(ident, dictionary))
}

pub fn check_bytes<'b, 's: 'b>(
buffer: &'b [u8],
tokenizer: &'s tokens::Tokenizer,
dictionary: &'s dyn Dictionary,
) -> impl Iterator<Item = Typo<'b>> {
tokenizer
.parse_bytes(buffer)
.flat_map(move |ident| process_ident(ident, dictionary))
}

fn process_ident<'i, 's: 'i>(
ident: tokens::Identifier<'i>,
dictionary: &'s dyn Dictionary,
) -> impl Iterator<Item = Typo<'i>> {
match dictionary.correct_ident(ident) {
Some(crate::Status::Valid) => itertools::Either::Left(None.into_iter()),
Some(corrections) => {
let typo = Typo {
byte_offset: ident.offset(),
typo: ident.token().into(),
corrections,
};
itertools::Either::Left(Some(typo).into_iter())
}
None => itertools::Either::Right(
ident
.split()
.filter_map(move |word| process_word(word, dictionary)),
),
}
}

fn process_word<'w, 's: 'w>(
word: tokens::Word<'w>,
dictionary: &'s dyn Dictionary,
) -> Option<Typo<'w>> {
match dictionary.correct_word(word) {
Some(crate::Status::Valid) => None,
Some(corrections) => {
let typo = Typo {
byte_offset: word.offset(),
typo: word.token().into(),
corrections,
};
Some(typo)
}
None => None,
}
}

/// An invalid term found in the buffer.
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct Typo<'m> {
pub byte_offset: usize,
pub typo: Cow<'m, str>,
pub corrections: crate::Status<'m>,
}

impl<'m> Typo<'m> {
pub fn into_owned(self) -> Typo<'static> {
Typo {
byte_offset: self.byte_offset,
typo: Cow::Owned(self.typo.into_owned()),
corrections: self.corrections.into_owned(),
}
}

pub fn borrow(&self) -> Typo<'_> {
Typo {
byte_offset: self.byte_offset,
typo: Cow::Borrowed(self.typo.as_ref()),
corrections: self.corrections.borrow(),
}
}
}

impl<'m> Default for Typo<'m> {
fn default() -> Self {
Self {
byte_offset: 0,
typo: "".into(),
corrections: crate::Status::Invalid,
}
}
}
15 changes: 0 additions & 15 deletions crates/typos/src/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@ pub trait Dictionary: Send + Sync {
fn correct_word<'s, 'w>(&'s self, word: crate::tokens::Word<'w>) -> Option<Status<'s>>;
}

pub(crate) struct NullDictionary;

impl Dictionary for NullDictionary {
fn correct_ident<'s, 'w>(
&'s self,
_ident: crate::tokens::Identifier<'w>,
) -> Option<Status<'s>> {
None
}

fn correct_word<'s, 'w>(&'s self, _word: crate::tokens::Word<'w>) -> Option<Status<'s>> {
None
}
}

/// Validity of a term in a Dictionary.
#[derive(Clone, PartialEq, Eq, Debug, serde::Serialize)]
#[serde(rename_all = "snake_case")]
Expand Down
4 changes: 2 additions & 2 deletions crates/typos/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod check;
mod dict;
mod parser;

pub mod tokens;

pub use check::*;
pub use dict::*;
pub use parser::*;
147 changes: 0 additions & 147 deletions crates/typos/src/parser.rs

This file was deleted.

27 changes: 6 additions & 21 deletions src/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,9 @@ impl FileChecker for Typos {
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<(), std::io::Error> {
let parser = typos::ParserBuilder::new()
.tokenizer(tokenizer)
.dictionary(dictionary)
.build();

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) {
for typo in typos::check_str(file_name, tokenizer, dictionary) {
let msg = report::Typo {
context: Some(report::PathContext { path }.into()),
buffer: std::borrow::Cow::Borrowed(file_name.as_bytes()),
Expand All @@ -97,7 +92,7 @@ impl FileChecker for Typos {
reporter.report(msg.into())?;
} else {
let mut accum_line_num = AccumulateLineNum::new();
for typo in parser.parse_bytes(&buffer) {
for typo in typos::check_bytes(&buffer, tokenizer, dictionary) {
let line_num = accum_line_num.line_num(&buffer, typo.byte_offset);
let (line, line_offset) = extract_line(&buffer, typo.byte_offset);
let msg = report::Typo {
Expand Down Expand Up @@ -129,11 +124,6 @@ impl FileChecker for FixTypos {
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<(), std::io::Error> {
let parser = typos::ParserBuilder::new()
.tokenizer(tokenizer)
.dictionary(dictionary)
.build();

if settings.check_files {
let (buffer, content_type) = read_file(path, reporter)?;
if !explicit && !settings.binary && content_type.is_binary() {
Expand All @@ -142,7 +132,7 @@ impl FileChecker for FixTypos {
} else {
let mut fixes = Vec::new();
let mut accum_line_num = AccumulateLineNum::new();
for typo in parser.parse_bytes(&buffer) {
for typo in typos::check_bytes(&buffer, tokenizer, dictionary) {
if is_fixable(&typo) {
fixes.push(typo.into_owned());
} else {
Expand All @@ -169,7 +159,7 @@ impl FileChecker for FixTypos {
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) {
for typo in typos::check_str(file_name, tokenizer, dictionary) {
if is_fixable(&typo) {
fixes.push(typo.into_owned());
} else {
Expand Down Expand Up @@ -211,11 +201,6 @@ impl FileChecker for DiffTypos {
dictionary: &dyn Dictionary,
reporter: &dyn report::Report,
) -> Result<(), std::io::Error> {
let parser = typos::ParserBuilder::new()
.tokenizer(tokenizer)
.dictionary(dictionary)
.build();

let mut content = Vec::new();
let mut new_content = Vec::new();
if settings.check_files {
Expand All @@ -226,7 +211,7 @@ impl FileChecker for DiffTypos {
} else {
let mut fixes = Vec::new();
let mut accum_line_num = AccumulateLineNum::new();
for typo in parser.parse_bytes(&buffer) {
for typo in typos::check_bytes(&buffer, tokenizer, dictionary) {
if is_fixable(&typo) {
fixes.push(typo.into_owned());
} else {
Expand Down Expand Up @@ -254,7 +239,7 @@ impl FileChecker for DiffTypos {
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) {
for typo in typos::check_str(file_name, tokenizer, dictionary) {
if is_fixable(&typo) {
fixes.push(typo.into_owned());
} else {
Expand Down

0 comments on commit b5f606f

Please sign in to comment.