1use std::{fmt, path::Path};
2
3use console::{style, Style};
4use similar::{ChangeTag, TextDiff};
5
6pub(crate) fn show(file_name: &Path, desired: &str, actual: &str) {
7 let diff = TextDiff::from_lines(actual, desired);
8 for (idx, group) in diff.grouped_ops(3).iter().enumerate() {
9 if idx == 0 {
10 println!("{:-<80}", file_name.to_string_lossy());
11 }
12 for op in group {
13 for change in diff.iter_inline_changes(op) {
14 let (sign, s) = match change.tag() {
15 ChangeTag::Delete => ("-", Style::new().red()),
16 ChangeTag::Insert => ("+", Style::new().green()),
17 ChangeTag::Equal => (" ", Style::new().dim()),
18 };
19 print!(
20 "{}{} |{}",
21 style(Line(change.old_index())).dim(),
22 style(Line(change.new_index())).dim(),
23 s.apply_to(sign).bold(),
24 );
25 for (emphasized, value) in change.iter_strings_lossy() {
26 if emphasized {
27 print!("{}", s.apply_to(value).underlined());
28 } else {
29 print!("{}", s.apply_to(value));
30 }
31 }
32 if change.missing_newline() {
33 println!();
34 }
35 }
36 }
37 println!(); }
39}
40struct Line(Option<usize>);
41
42impl fmt::Display for Line {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 match self.0 {
45 None => write!(f, " "),
46 Some(idx) => write!(f, "{:>4}", idx + 1),
47 }
48 }
49}