Skip to content

Commit 90a5d2d

Browse files
authored
Merge pull request #7 from PurpleBooth/switch-to-dissimilar
fix: Switch from difference to dissimilar
2 parents edeee23 + a690b65 commit 90a5d2d

File tree

2 files changed

+52
-21
lines changed

2 files changed

+52
-21
lines changed

Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ is-it-maintained-open-issues = { repository = "https://github.com/CAD97/colored-
1818
maintenance = { status = "passively-maintained" }
1919

2020
[dependencies]
21-
difference = "2.0.0"
21+
dissimilar = "1.0"
2222
ansi_term = "0.11.0"
2323
itertools = { version = "0.7.8", default-features = false }
24+
[dev-dependencies]
25+
regex = "1.5.4"

src/lib.rs

+49-20
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
extern crate ansi_term;
2-
extern crate difference;
2+
extern crate dissimilar;
33
extern crate itertools;
4+
#[cfg(test)]
5+
extern crate regex;
46

57
use ansi_term::{ANSIGenericString, Colour};
6-
use difference::{Changeset, Difference};
8+
use dissimilar::Chunk;
79
use itertools::Itertools;
810
use std::fmt;
911

@@ -53,33 +55,32 @@ impl<'a> fmt::Display for PrettyDifference<'a> {
5355

5456
/// Format the difference between strings using GitHub-like formatting with ANSI coloring.
5557
pub fn diff(f: &mut fmt::Formatter, expected: &str, actual: &str) -> fmt::Result {
56-
let changeset = Changeset::new(expected, actual, "\n");
58+
let changeset = dissimilar::diff(expected, actual);
5759
fmt_changeset(f, &changeset)
5860
}
5961

60-
fn fmt_changeset(f: &mut fmt::Formatter, changeset: &Changeset) -> fmt::Result {
62+
fn fmt_changeset(f: &mut fmt::Formatter, changeset: &Vec<Chunk>) -> fmt::Result {
6163
enable_ansi();
6264

6365
writeln!(f, "{} {} / {} {}",
6466
red(LEFT), red("left"),
6567
green(RIGHT), green("right"),
6668
)?;
6769

68-
let diffs = &changeset.diffs;
69-
for (i, diff) in diffs.iter().enumerate() {
70+
for (i, diff) in changeset.iter().enumerate() {
7071
match diff {
71-
Difference::Same(text) => {
72+
Chunk::Equal(text) => {
7273
format_same(f, text)?;
7374
}
74-
Difference::Add(added) => {
75-
if let Some(Difference::Rem(removed)) = i.checked_sub(1).map(|i| &diffs[i]) {
75+
Chunk::Insert(added) => {
76+
if let Some(Chunk::Delete(removed)) = i.checked_sub(1).map(|i| &changeset[i]) {
7677
format_add_rem(f, added, removed)?;
7778
} else {
7879
format_add(f, added)?;
7980
}
8081
}
81-
Difference::Rem(removed) => {
82-
if let Some(Difference::Add(_)) = diffs.get(i + 1) {
82+
Chunk::Delete(removed) => {
83+
if let Some(Chunk::Insert(_)) = changeset.get(i + 1) {
8384
continue;
8485
} else {
8586
format_rem(f, removed)?;
@@ -92,23 +93,23 @@ fn fmt_changeset(f: &mut fmt::Formatter, changeset: &Changeset) -> fmt::Result {
9293
}
9394

9495
fn format_add_rem(f: &mut fmt::Formatter, added: &str, removed: &str) -> fmt::Result {
95-
let Changeset { diffs, .. } = Changeset::new(removed, added, "");
96+
let diffs = dissimilar::diff(removed, added);
9697

9798
// LEFT (removed)
9899
write!(f, "{}", red(LEFT))?;
99100
for diff in &diffs {
100101
match diff {
101-
Difference::Same(text) => {
102+
Chunk::Equal(text) => {
102103
for blob in Itertools::intersperse(text.split('\n'), NL_LEFT) {
103104
write!(f, "{}", red(blob))?;
104105
}
105106
}
106-
Difference::Rem(text) => {
107-
for blob in Itertools::intersperse(text.split('\n'), NL_LEFT) {
107+
Chunk::Delete(text) => {
108+
for blob in Itertools::intersperse(text.split('\n'), NL_LEFT) {
108109
write!(f, "{}", on_red(blob))?;
109110
}
110111
}
111-
Difference::Add(_) => continue,
112+
Chunk::Insert(_) => continue,
112113
}
113114
}
114115
writeln!(f)?;
@@ -117,17 +118,17 @@ fn format_add_rem(f: &mut fmt::Formatter, added: &str, removed: &str) -> fmt::Re
117118
write!(f, "{}", green(RIGHT))?;
118119
for diff in &diffs {
119120
match diff {
120-
Difference::Same(text) => {
121+
Chunk::Equal(text) => {
121122
for blob in Itertools::intersperse(text.split('\n'), NL_RIGHT) {
122123
write!(f, "{}", green(blob))?;
123124
}
124125
}
125-
Difference::Add(text) => {
126-
for blob in Itertools::intersperse(text.split('\n'), NL_RIGHT) {
126+
Chunk::Insert(text) => {
127+
for blob in Itertools::intersperse(text.split('\n'), NL_RIGHT) {
127128
write!(f, "{}", on_green(blob))?;
128129
}
129130
}
130-
Difference::Rem(_) => continue,
131+
Chunk::Delete(_) => continue,
131132
}
132133
}
133134
writeln!(f)?;
@@ -158,6 +159,8 @@ fn format_rem(f: &mut fmt::Formatter, text: &str) -> fmt::Result {
158159

159160
#[cfg(test)]
160161
mod tests {
162+
use regex::Regex;
163+
161164
use super::*;
162165

163166
#[test]
@@ -168,4 +171,30 @@ mod tests {
168171
}
169172
.to_string();
170173
}
174+
175+
#[test]
176+
fn color_free_diff() {
177+
let diff: String = PrettyDifference {
178+
expected: "a\nb\nc",
179+
actual: "\nb\ncc",
180+
}
181+
.to_string();
182+
183+
let re = Regex::new(r"\u{1b}\[[0-9;]*m").unwrap();
184+
assert_eq!(
185+
re.replace_all(&diff, ""),
186+
"< left / > right\n<a\n \n b\n c\n>c\n"
187+
);
188+
}
189+
190+
#[test]
191+
fn color_diff() {
192+
let diff: String = PrettyDifference {
193+
expected: "a\nb\nc",
194+
actual: "\nb\ncc",
195+
}
196+
.to_string();
197+
198+
assert_eq!(diff, "\u{1b}[31m<\u{1b}[0m \u{1b}[31mleft\u{1b}[0m / \u{1b}[32m>\u{1b}[0m \u{1b}[32mright\u{1b}[0m\n\u{1b}[31m<\u{1b}[0m\u{1b}[31ma\u{1b}[0m\n \n b\n c\n\u{1b}[32m>\u{1b}[0m\u{1b}[32mc\u{1b}[0m\n");
199+
}
171200
}

0 commit comments

Comments
 (0)