11extern crate ansi_term;
2- extern crate difference ;
2+ extern crate dissimilar ;
33extern crate itertools;
4+ #[ cfg( test) ]
5+ extern crate regex;
46
57use ansi_term:: { ANSIGenericString , Colour } ;
6- use difference :: { Changeset , Difference } ;
8+ use dissimilar :: Chunk ;
79use itertools:: Itertools ;
810use 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.
5557pub 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
9495fn 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) ]
160161mod 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\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+ }
171200}
0 commit comments