Skip to content

Commit

Permalink
refactor: Split out typos-dict
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Aug 8, 2019
1 parent 164ee9c commit 1bdd1c9
Show file tree
Hide file tree
Showing 17 changed files with 173 additions and 127 deletions.
36 changes: 28 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["typos"]
members = ["typos", "typos-dict"]

[package]
name = "typos-cli"
Expand All @@ -23,6 +23,7 @@ iterate_unstable = []

[dependencies]
typos = { version = "0.1", path = "typos" }
typos-dict = { version = "0.1", path = "typos-dict" }
failure = "0.1"
structopt = "0.2"
clap = "2"
Expand Down
6 changes: 3 additions & 3 deletions benches/corrections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ extern crate test;

#[bench]
fn load_corrections(b: &mut test::Bencher) {
b.iter(|| typos::BuiltIn::new());
b.iter(|| typos_dict::BuiltIn::new());
}

#[bench]
fn correct_word_hit(b: &mut test::Bencher) {
let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let input = typos::tokens::Word::new("successs", 0).unwrap();
assert_eq!(
corrections.correct_word(input),
Expand All @@ -20,7 +20,7 @@ fn correct_word_hit(b: &mut test::Bencher) {

#[bench]
fn correct_word_miss(b: &mut test::Bencher) {
let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let input = typos::tokens::Word::new("success", 0).unwrap();
assert_eq!(corrections.correct_word(input), None);
b.iter(|| corrections.correct_word(input));
Expand Down
2 changes: 1 addition & 1 deletion benches/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ fn main() {
}
";

pub const CORPUS: &str = include_str!("../typos/assets/words.csv");
pub const CORPUS: &str = include_str!("../typos-dict/assets/words.csv");
12 changes: 6 additions & 6 deletions benches/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn process_empty(b: &mut test::Bencher) {
let sample_path = temp.child("sample");
sample_path.write_str(data::EMPTY).unwrap();

let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let parser = typos::tokens::Parser::new();
let checks = typos::checks::CheckSettings::new().build(&corrections, &parser);
b.iter(|| checks.check_file(sample_path.path(), true, typos::report::print_silent));
Expand All @@ -26,7 +26,7 @@ fn process_no_tokens(b: &mut test::Bencher) {
let sample_path = temp.child("sample");
sample_path.write_str(data::NO_TOKENS).unwrap();

let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let parser = typos::tokens::Parser::new();
let checks = typos::checks::CheckSettings::new().build(&corrections, &parser);
b.iter(|| checks.check_file(sample_path.path(), true, typos::report::print_silent));
Expand All @@ -40,7 +40,7 @@ fn process_single_token(b: &mut test::Bencher) {
let sample_path = temp.child("sample");
sample_path.write_str(data::SINGLE_TOKEN).unwrap();

let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let parser = typos::tokens::Parser::new();
let checks = typos::checks::CheckSettings::new().build(&corrections, &parser);
b.iter(|| checks.check_file(sample_path.path(), true, typos::report::print_silent));
Expand All @@ -54,7 +54,7 @@ fn process_sherlock(b: &mut test::Bencher) {
let sample_path = temp.child("sample");
sample_path.write_str(data::SHERLOCK).unwrap();

let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let parser = typos::tokens::Parser::new();
let checks = typos::checks::CheckSettings::new().build(&corrections, &parser);
b.iter(|| checks.check_file(sample_path.path(), true, typos::report::print_silent));
Expand All @@ -68,7 +68,7 @@ fn process_code(b: &mut test::Bencher) {
let sample_path = temp.child("sample");
sample_path.write_str(data::CODE).unwrap();

let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let parser = typos::tokens::Parser::new();
let checks = typos::checks::CheckSettings::new().build(&corrections, &parser);
b.iter(|| checks.check_file(sample_path.path(), true, typos::report::print_silent));
Expand All @@ -82,7 +82,7 @@ fn process_corpus(b: &mut test::Bencher) {
let sample_path = temp.child("sample");
sample_path.write_str(data::CORPUS).unwrap();

let corrections = typos::BuiltIn::new();
let corrections = typos_dict::BuiltIn::new();
let parser = typos::tokens::Parser::new();
let checks = typos::checks::CheckSettings::new().build(&corrections, &parser);
b.iter(|| checks.check_file(sample_path.path(), true, typos::report::print_silent));
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ fn run() -> Result<i32, failure::Error> {
config.default.update(&args.overrides);
let config = config;

let dictionary = typos::BuiltIn::new();
let dictionary = typos_dict::BuiltIn::new();

let parser = typos::tokens::ParserBuilder::new()
.ignore_hex(config.default.ignore_hex())
Expand Down
31 changes: 31 additions & 0 deletions typos-dict/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "typos-dict"
version = "0.1.0"
authors = ["Ed Page <[email protected]>"]
description = "Source Code Spelling Correction"
repository = "https://github.com/epage/typos"
documentation = "https://docs.rs/typos-dict"
readme = "README.md"
categories = ["development-tools", "text-processing"]
keywords = ["development", "spelling"]
license = "MIT"
edition = "2018"

[badges]
travis-ci = { repository = "epage/typos" }
appveyor = { repository = "epage/typos" }

[features]
# Support quickly iterating
iterate_unstable = []

[dependencies]
typos = { version = "0.1", path = "../typos" }
phf = { version = "0.7", features = ["unicase"] }
unicase = "1.1"
log = "0.4"

[build-dependencies]
phf_codegen = "0.7"
csv = "1.0"
unicase = "1.1"
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
97 changes: 97 additions & 0 deletions typos-dict/src/dict.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use std::borrow::Cow;

use unicase::UniCase;

use typos::tokens::Case;

#[derive(Default)]
pub struct BuiltIn {}

impl BuiltIn {
pub fn new() -> Self {
Self {}
}

pub fn correct_ident<'s, 'w>(
&'s self,
_ident: typos::tokens::Identifier<'w>,
) -> Option<Cow<'s, str>> {
None
}

pub fn correct_word<'s, 'w>(&'s self, word: typos::tokens::Word<'w>) -> Option<Cow<'s, str>> {
map_lookup(&crate::dict_codegen::WORD_DICTIONARY, word.token())
.map(|s| case_correct(s, word.case()))
}
}

impl typos::Dictionary for BuiltIn {
fn correct_ident<'s, 'w>(
&'s self,
ident: typos::tokens::Identifier<'w>,
) -> Option<Cow<'s, str>> {
BuiltIn::correct_ident(self, ident)
}

fn correct_word<'s, 'w>(&'s self, word: typos::tokens::Word<'w>) -> Option<Cow<'s, str>> {
BuiltIn::correct_word(self, word)
}
}

fn map_lookup(
map: &'static phf::Map<UniCase<&'static str>, &'static str>,
key: &str,
) -> Option<&'static str> {
// This transmute should be safe as `get` will not store the reference with
// the expanded lifetime. This is due to `Borrow` being overly strict and
// can't have an impl for `&'static str` to `Borrow<&'a str>`.
//
//
// See https://github.com/rust-lang/rust/issues/28853#issuecomment-158735548
unsafe {
let key = ::std::mem::transmute::<_, &'static str>(key);
map.get(&UniCase(key)).cloned()
}
}

fn case_correct(correction: &str, case: Case) -> Cow<'_, str> {
match case {
Case::Lower | Case::None => correction.into(),
Case::Title => {
let mut title = String::with_capacity(correction.as_bytes().len());
let mut char_indices = correction.char_indices();
if let Some((_, c)) = char_indices.next() {
title.extend(c.to_uppercase());
if let Some((i, _)) = char_indices.next() {
title.push_str(&correction[i..]);
}
}
title.into()
}
Case::Scream => correction
.chars()
.flat_map(|c| c.to_uppercase())
.collect::<String>()
.into(),
}
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_case_correct() {
let cases = [
("foo", Case::Lower, "foo"),
("foo", Case::None, "foo"),
("foo", Case::Title, "Foo"),
("foo", Case::Scream, "FOO"),
("fOo", Case::None, "fOo"),
];
for (correction, case, expected) in cases.iter() {
let actual = case_correct(correction, *case);
assert_eq!(*expected, actual);
}
}
}
File renamed without changes.
4 changes: 4 additions & 0 deletions typos-dict/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod dict;
mod dict_codegen;

pub use crate::dict::*;
10 changes: 0 additions & 10 deletions typos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ edition = "2018"
travis-ci = { repository = "epage/typos" }
appveyor = { repository = "epage/typos" }

[features]
# Support quickly iterating
iterate_unstable = []

[dependencies]
failure = "0.1"
phf = { version = "0.7", features = ["unicase"] }
regex = "1.0"
lazy_static = "1.2.0"
serde = { version = "1.0", features = ["derive"] }
Expand All @@ -32,8 +27,3 @@ bstr = "0.2"
log = "0.4"
unicode-segmentation = "1.3.0"
derive_more = "0.15.0"

[build-dependencies]
phf_codegen = "0.7"
csv = "1.0"
unicase = "1.1"
Loading

0 comments on commit 1bdd1c9

Please sign in to comment.