1 use std::collections::VecDeque;
3 #[derive(Debug, PartialEq)]
10 #[derive(Debug, PartialEq)]
13 pub lines: Vec<DiffLine>,
17 fn new(line_number: u32) -> Mismatch {
18 Mismatch { line_number, lines: Vec::new() }
22 // Produces a diff between the expected output and actual output.
23 pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
24 let mut line_number = 1;
25 let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
26 let mut lines_since_mismatch = context_size + 1;
27 let mut results = Vec::new();
28 let mut mismatch = Mismatch::new(0);
30 for result in diff::lines(expected, actual) {
32 diff::Result::Left(str) => {
33 if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
34 results.push(mismatch);
35 mismatch = Mismatch::new(line_number - context_queue.len() as u32);
38 while let Some(line) = context_queue.pop_front() {
39 mismatch.lines.push(DiffLine::Context(line.to_owned()));
42 mismatch.lines.push(DiffLine::Expected(str.to_owned()));
44 lines_since_mismatch = 0;
46 diff::Result::Right(str) => {
47 if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
48 results.push(mismatch);
49 mismatch = Mismatch::new(line_number - context_queue.len() as u32);
52 while let Some(line) = context_queue.pop_front() {
53 mismatch.lines.push(DiffLine::Context(line.to_owned()));
56 mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
57 lines_since_mismatch = 0;
59 diff::Result::Both(str, _) => {
60 if context_queue.len() >= context_size {
61 let _ = context_queue.pop_front();
64 if lines_since_mismatch < context_size {
65 mismatch.lines.push(DiffLine::Context(str.to_owned()));
66 } else if context_size > 0 {
67 context_queue.push_back(str);
71 lines_since_mismatch += 1;
76 results.push(mismatch);
82 pub(crate) fn write_diff(expected: &str, actual: &str, context_size: usize) -> String {
84 let mut output = String::new();
85 let diff_results = make_diff(expected, actual, context_size);
86 for result in diff_results {
87 let mut line_number = result.line_number;
88 for line in result.lines {
90 DiffLine::Expected(e) => {
91 writeln!(output, "-\t{}", e).unwrap();
94 DiffLine::Context(c) => {
95 writeln!(output, "{}\t{}", line_number, c).unwrap();
98 DiffLine::Resulting(r) => {
99 writeln!(output, "+\t{}", r).unwrap();
103 writeln!(output).unwrap();