@@ -41,7 +41,12 @@ impl Mismatch {
4141}
4242
4343// Produces a diff between the expected output and actual output.
44- fn make_diff ( expected : & [ u8 ] , actual : & [ u8 ] , context_size : usize ) -> Vec < Mismatch > {
44+ fn make_diff (
45+ expected : & [ u8 ] ,
46+ actual : & [ u8 ] ,
47+ context_size : usize ,
48+ stop_early : bool ,
49+ ) -> Vec < Mismatch > {
4550 let mut line_number_expected = 1 ;
4651 let mut line_number_actual = 1 ;
4752 let mut context_queue: VecDeque < & [ u8 ] > = VecDeque :: with_capacity ( context_size) ;
@@ -191,6 +196,10 @@ fn make_diff(expected: &[u8], actual: &[u8], context_size: usize) -> Vec<Mismatc
191196 line_number_actual += 1 ;
192197 }
193198 }
199+ if stop_early && !results. is_empty ( ) {
200+ // Optimization: stop analyzing the files as soon as there are any differences
201+ return results;
202+ }
194203 }
195204
196205 results. push ( mismatch) ;
@@ -260,12 +269,16 @@ pub fn diff(
260269 actual : & [ u8 ] ,
261270 actual_filename : & str ,
262271 context_size : usize ,
272+ stop_early : bool ,
263273) -> Vec < u8 > {
264274 let mut output = format ! ( "*** {expected_filename}\t \n --- {actual_filename}\t \n " ) . into_bytes ( ) ;
265- let diff_results = make_diff ( expected, actual, context_size) ;
275+ let diff_results = make_diff ( expected, actual, context_size, stop_early ) ;
266276 if diff_results. is_empty ( ) {
267277 return Vec :: new ( ) ;
268- } ;
278+ }
279+ if stop_early {
280+ return output;
281+ }
269282 for result in diff_results {
270283 let mut line_number_expected = result. line_number_expected ;
271284 let mut line_number_actual = result. line_number_actual ;
@@ -404,8 +417,14 @@ mod tests {
404417 }
405418 // This test diff is intentionally reversed.
406419 // We want it to turn the alef into bet.
407- let diff =
408- diff ( & alef, "a/alef" , & bet, & format ! ( "{target}/alef" ) , 2 ) ;
420+ let diff = diff (
421+ & alef,
422+ "a/alef" ,
423+ & bet,
424+ & format ! ( "{target}/alef" ) ,
425+ 2 ,
426+ false ,
427+ ) ;
409428 File :: create ( & format ! ( "{target}/ab.diff" ) )
410429 . unwrap ( )
411430 . write_all ( & diff)
@@ -477,8 +496,14 @@ mod tests {
477496 }
478497 // This test diff is intentionally reversed.
479498 // We want it to turn the alef into bet.
480- let diff =
481- diff ( & alef, "a/alef_" , & bet, & format ! ( "{target}/alef_" ) , 2 ) ;
499+ let diff = diff (
500+ & alef,
501+ "a/alef_" ,
502+ & bet,
503+ & format ! ( "{target}/alef_" ) ,
504+ 2 ,
505+ false ,
506+ ) ;
482507 File :: create ( & format ! ( "{target}/ab_.diff" ) )
483508 . unwrap ( )
484509 . write_all ( & diff)
@@ -553,8 +578,14 @@ mod tests {
553578 } ;
554579 // This test diff is intentionally reversed.
555580 // We want it to turn the alef into bet.
556- let diff =
557- diff ( & alef, "a/alefx" , & bet, & format ! ( "{target}/alefx" ) , 2 ) ;
581+ let diff = diff (
582+ & alef,
583+ "a/alefx" ,
584+ & bet,
585+ & format ! ( "{target}/alefx" ) ,
586+ 2 ,
587+ false ,
588+ ) ;
558589 File :: create ( & format ! ( "{target}/abx.diff" ) )
559590 . unwrap ( )
560591 . write_all ( & diff)
@@ -632,8 +663,14 @@ mod tests {
632663 }
633664 // This test diff is intentionally reversed.
634665 // We want it to turn the alef into bet.
635- let diff =
636- diff ( & alef, "a/alefr" , & bet, & format ! ( "{target}/alefr" ) , 2 ) ;
666+ let diff = diff (
667+ & alef,
668+ "a/alefr" ,
669+ & bet,
670+ & format ! ( "{target}/alefr" ) ,
671+ 2 ,
672+ false ,
673+ ) ;
637674 File :: create ( & format ! ( "{target}/abr.diff" ) )
638675 . unwrap ( )
639676 . write_all ( & diff)
@@ -662,4 +699,69 @@ mod tests {
662699 }
663700 }
664701 }
702+
703+ #[ test]
704+ fn test_stop_early ( ) {
705+ let from_filename = "foo" ;
706+ let from = vec ! [ "a" , "b" , "c" , "" ] . join ( "\n " ) ;
707+ let to_filename = "bar" ;
708+ let to = vec ! [ "a" , "d" , "c" , "" ] . join ( "\n " ) ;
709+ let context_size: usize = 3 ;
710+
711+ let diff_full = diff (
712+ from. as_bytes ( ) ,
713+ from_filename,
714+ to. as_bytes ( ) ,
715+ to_filename,
716+ context_size,
717+ false ,
718+ ) ;
719+ let expected_full = vec ! [
720+ "*** foo\t " ,
721+ "--- bar\t " ,
722+ "***************" ,
723+ "*** 1,3 ****" ,
724+ " a" ,
725+ "! b" ,
726+ " c" ,
727+ "--- 1,3 ----" ,
728+ " a" ,
729+ "! d" ,
730+ " c" ,
731+ "" ,
732+ ]
733+ . join ( "\n " ) ;
734+ assert_eq ! ( diff_full, expected_full. as_bytes( ) ) ;
735+
736+ let diff_brief = diff (
737+ from. as_bytes ( ) ,
738+ from_filename,
739+ to. as_bytes ( ) ,
740+ to_filename,
741+ context_size,
742+ true ,
743+ ) ;
744+ let expected_brief = vec ! [ "*** foo\t " , "--- bar\t " , "" ] . join ( "\n " ) ;
745+ assert_eq ! ( diff_brief, expected_brief. as_bytes( ) ) ;
746+
747+ let nodiff_full = diff (
748+ from. as_bytes ( ) ,
749+ from_filename,
750+ from. as_bytes ( ) ,
751+ to_filename,
752+ context_size,
753+ false ,
754+ ) ;
755+ assert ! ( nodiff_full. is_empty( ) ) ;
756+
757+ let nodiff_brief = diff (
758+ from. as_bytes ( ) ,
759+ from_filename,
760+ from. as_bytes ( ) ,
761+ to_filename,
762+ context_size,
763+ true ,
764+ ) ;
765+ assert ! ( nodiff_brief. is_empty( ) ) ;
766+ }
665767}
0 commit comments