1
1
extern crate ansi_term;
2
- extern crate difference ;
2
+ extern crate dissimilar ;
3
3
extern crate itertools;
4
+ #[ cfg( test) ]
5
+ extern crate regex;
4
6
5
7
use ansi_term:: { ANSIGenericString , Colour } ;
6
- use difference :: { Changeset , Difference } ;
8
+ use dissimilar :: Chunk ;
7
9
use itertools:: Itertools ;
8
10
use std:: fmt;
9
11
@@ -53,33 +55,32 @@ impl<'a> fmt::Display for PrettyDifference<'a> {
53
55
54
56
/// Format the difference between strings using GitHub-like formatting with ANSI coloring.
55
57
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) ;
57
59
fmt_changeset ( f, & changeset)
58
60
}
59
61
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 {
61
63
enable_ansi ( ) ;
62
64
63
65
writeln ! ( f, "{} {} / {} {}" ,
64
66
red( LEFT ) , red( "left" ) ,
65
67
green( RIGHT ) , green( "right" ) ,
66
68
) ?;
67
69
68
- let diffs = & changeset. diffs ;
69
- for ( i, diff) in diffs. iter ( ) . enumerate ( ) {
70
+ for ( i, diff) in changeset. iter ( ) . enumerate ( ) {
70
71
match diff {
71
- Difference :: Same ( text) => {
72
+ Chunk :: Equal ( text) => {
72
73
format_same ( f, text) ?;
73
74
}
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] ) {
76
77
format_add_rem ( f, added, removed) ?;
77
78
} else {
78
79
format_add ( f, added) ?;
79
80
}
80
81
}
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 ) {
83
84
continue ;
84
85
} else {
85
86
format_rem ( f, removed) ?;
@@ -92,23 +93,23 @@ fn fmt_changeset(f: &mut fmt::Formatter, changeset: &Changeset) -> fmt::Result {
92
93
}
93
94
94
95
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) ;
96
97
97
98
// LEFT (removed)
98
99
write ! ( f, "{}" , red( LEFT ) ) ?;
99
100
for diff in & diffs {
100
101
match diff {
101
- Difference :: Same ( text) => {
102
+ Chunk :: Equal ( text) => {
102
103
for blob in Itertools :: intersperse ( text. split ( '\n' ) , NL_LEFT ) {
103
104
write ! ( f, "{}" , red( blob) ) ?;
104
105
}
105
106
}
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 ) {
108
109
write ! ( f, "{}" , on_red( blob) ) ?;
109
110
}
110
111
}
111
- Difference :: Add ( _) => continue ,
112
+ Chunk :: Insert ( _) => continue ,
112
113
}
113
114
}
114
115
writeln ! ( f) ?;
@@ -117,17 +118,17 @@ fn format_add_rem(f: &mut fmt::Formatter, added: &str, removed: &str) -> fmt::Re
117
118
write ! ( f, "{}" , green( RIGHT ) ) ?;
118
119
for diff in & diffs {
119
120
match diff {
120
- Difference :: Same ( text) => {
121
+ Chunk :: Equal ( text) => {
121
122
for blob in Itertools :: intersperse ( text. split ( '\n' ) , NL_RIGHT ) {
122
123
write ! ( f, "{}" , green( blob) ) ?;
123
124
}
124
125
}
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 ) {
127
128
write ! ( f, "{}" , on_green( blob) ) ?;
128
129
}
129
130
}
130
- Difference :: Rem ( _) => continue ,
131
+ Chunk :: Delete ( _) => continue ,
131
132
}
132
133
}
133
134
writeln ! ( f) ?;
@@ -158,6 +159,8 @@ fn format_rem(f: &mut fmt::Formatter, text: &str) -> fmt::Result {
158
159
159
160
#[ cfg( test) ]
160
161
mod tests {
162
+ use regex:: Regex ;
163
+
161
164
use super :: * ;
162
165
163
166
#[ test]
@@ -168,4 +171,30 @@ mod tests {
168
171
}
169
172
. to_string ( ) ;
170
173
}
174
+
175
+ #[ test]
176
+ fn color_free_diff ( ) {
177
+ let diff: String = PrettyDifference {
178
+ expected : "a\n b\n c" ,
179
+ actual : "\n b\n cc" ,
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\n b\n c" ,
194
+ actual : "\n b\n cc" ,
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
+ }
171
200
}
0 commit comments