Skip to content

Commit

Permalink
feat(report): Diff output mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Ed Page committed Nov 12, 2020
1 parent 7a1fac7 commit d258e62
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 8 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ log = "0.4"
env_logger = "0.8"
bstr = "0.2"
ahash = "0.5.8"
difflib = "0.4"

[dev-dependencies]
assert_fs = "1.0"
Expand Down
4 changes: 4 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ pub(crate) struct Args {
/// Ignore implicit configuration files.
pub(crate) isolated: bool,

#[structopt(long)]
/// Print a diff of what would change
pub(crate) diff: bool,

#[structopt(long, short = "w")]
/// Write corrections out
pub(crate) write_changes: bool,
Expand Down
93 changes: 93 additions & 0 deletions src/diff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use std::collections::BTreeMap;
use std::sync;

use bstr::ByteSlice;

pub struct Diff<'r> {
reporter: &'r dyn typos::report::Report,
deferred: sync::Mutex<crate::replace::Deferred>,
}

impl<'r> Diff<'r> {
pub(crate) fn new(reporter: &'r dyn typos::report::Report) -> Self {
Self {
reporter,
deferred: sync::Mutex::new(crate::replace::Deferred::default()),
}
}

pub fn show(&self) -> Result<(), std::io::Error> {
let deferred = self.deferred.lock().unwrap();

for (path, corrections) in deferred.content.iter() {
let buffer = std::fs::read(path)?;

let mut original = Vec::new();
let mut corrected = Vec::new();
for (line_idx, line) in buffer.lines_with_terminator().enumerate() {
original.push(String::from_utf8_lossy(line).into_owned());

let line_num = line_idx + 1;
let line = if let Some(corrections) = corrections.get(&line_num) {
let line = line.to_vec();
crate::replace::correct(line, &corrections)
} else {
line.to_owned()
};
corrected.push(String::from_utf8_lossy(&line).into_owned())
}

let display_path = path.display().to_string();
let diff = difflib::unified_diff(
&original,
&corrected,
display_path.as_str(),
display_path.as_str(),
"original",
"corrected",
0,
);
for line in diff {
print!("{}", line);
}
}

Ok(())
}
}

impl<'r> typos::report::Report for Diff<'r> {
fn report(&self, msg: typos::report::Message<'_>) -> bool {
let typo = match &msg {
typos::report::Message::Typo(typo) => typo,
_ => return self.reporter.report(msg),
};

let corrections = match &typo.corrections {
typos::Status::Corrections(corrections) if corrections.len() == 1 => corrections,
_ => return self.reporter.report(msg),
};

match &typo.context {
Some(typos::report::Context::File(file)) => {
let path = file.path.to_owned();
let line_num = file.line_num;
let correction = crate::replace::Correction::new(
typo.byte_offset,
typo.typo,
corrections[0].as_ref(),
);
let mut deferred = self.deferred.lock().unwrap();
let content = deferred
.content
.entry(path)
.or_insert_with(BTreeMap::new)
.entry(line_num)
.or_insert_with(Vec::new);
content.push(correction);
false
}
_ => msg.is_correction(),
}
}
}
10 changes: 8 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod args;
mod checks;
mod config;
mod dict;
mod diff;
mod replace;

fn main() {
Expand Down Expand Up @@ -86,7 +87,10 @@ fn run() -> Result<i32, anyhow::Error> {

let mut reporter = args.format.reporter();
let replace_reporter = replace::Replace::new(reporter);
if args.write_changes {
let diff_reporter = diff::Diff::new(reporter);
if args.diff {
reporter = &diff_reporter;
} else if args.write_changes {
reporter = &replace_reporter;
}

Expand Down Expand Up @@ -129,7 +133,9 @@ fn run() -> Result<i32, anyhow::Error> {
errors_found = true;
}

if args.write_changes {
if args.diff {
diff_reporter.show()?;
} else if args.write_changes {
replace_reporter.write()?;
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/replace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,20 @@ impl<'r> typos::report::Report for Replace<'r> {
}

#[derive(Clone, Debug, Default)]
struct Deferred {
content: BTreeMap<path::PathBuf, BTreeMap<usize, Vec<Correction>>>,
paths: BTreeMap<path::PathBuf, Vec<Correction>>,
pub(crate) struct Deferred {
pub(crate) content: BTreeMap<path::PathBuf, BTreeMap<usize, Vec<Correction>>>,
pub(crate) paths: BTreeMap<path::PathBuf, Vec<Correction>>,
}

#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
struct Correction {
pub(crate) struct Correction {
pub byte_offset: usize,
pub typo: Vec<u8>,
pub correction: Vec<u8>,
}

impl Correction {
fn new(byte_offset: usize, typo: &str, correction: &str) -> Self {
pub(crate) fn new(byte_offset: usize, typo: &str, correction: &str) -> Self {
Self {
byte_offset,
typo: typo.as_bytes().to_vec(),
Expand All @@ -119,7 +119,7 @@ impl Correction {
}
}

fn correct(mut line: Vec<u8>, corrections: &[Correction]) -> Vec<u8> {
pub(crate) fn correct(mut line: Vec<u8>, corrections: &[Correction]) -> Vec<u8> {
let mut corrections: Vec<_> = corrections.iter().collect();
corrections.sort_unstable();
corrections.reverse();
Expand Down

0 comments on commit d258e62

Please sign in to comment.