1use crate::result::LineResult;
3use owo_colors::AnsiColors::{Black, Green, Red, Yellow};
4use owo_colors::OwoColorize;
5use std::fmt::Write;
6
7pub(crate) fn diff_line_result(line: &LineResult, no_diff_bg_color: bool) -> String {
9 let mut err_color = Red;
10 if line.severity.is_warning() {
11 err_color = Yellow;
12 }
13
14 let on_color = match no_diff_bg_color {
15 true => on_color_transparent,
16 false => on_color,
17 };
18
19 diff_lines_with_err_color(line.old.trim(), line.new.trim(), err_color, on_color)
20}
21
22#[allow(dead_code)]
23pub(crate) fn diff_lines(old_str: &str, new_str: &str) -> String {
24 diff_lines_with_err_color(old_str, new_str, Red, on_color)
25}
26
27type OnColorFn = fn(s: char, color: owo_colors::AnsiColors) -> String;
28
29#[inline]
30fn on_color(s: char, color: owo_colors::AnsiColors) -> String {
31 let t = s.on_color(color).color(Black);
32 format!("{t}")
33}
34
35#[inline]
36fn on_color_transparent(s: char, color: owo_colors::AnsiColors) -> String {
37 let t = s.color(color);
38 format!("{t}")
39}
40
41#[allow(unused_must_use)]
49pub(crate) fn diff_lines_with_err_color(
50 old_str: &str,
51 new_str: &str,
52 err_color: owo_colors::AnsiColors,
53 on_color: OnColorFn,
54) -> String {
55 let diffs = diff::lines(old_str, new_str);
56
57 let mut out = String::new();
58
59 for i in 0..diffs.len() {
60 match diffs[i] {
61 diff::Result::Both(x, _) => {
62 out.push(' ');
63 out.push_str(x);
64 out.push('\n');
65 }
66 diff::Result::Left(x) => {
68 match diffs.get(i + 1) {
69 Some(diff::Result::Right(y)) => {
70 write!(out, "{}", "-".color(err_color));
71 let sub_diffs = diff::chars(y, x);
72 for c in sub_diffs {
73 match c {
74 diff::Result::Both(z, _) => {
75 write!(out, "{}", z.color(err_color));
76 }
77 diff::Result::Right(z) => {
78 write!(out, "{}", on_color(z, err_color));
79 }
80 _ => (),
81 }
82 }
83 out.push('\n');
84 }
85 _ => {
86 writeln!(out, "{}", format!("-{x}").color(err_color));
87 }
88 };
89 }
90 diff::Result::Right(x) => {
92 match diffs.get(i - 1) {
93 Some(diff::Result::Left(y)) => {
94 write!(out, "{}", "+".color(Green));
95 let sub_diffs = diff::chars(y, x);
96
97 for c in sub_diffs {
98 match c {
99 diff::Result::Both(z, _) => {
100 write!(out, "{}", z.color(Green));
101 }
102 diff::Result::Right(z) => {
103 write!(out, "{}", on_color(z, Green));
104 }
105 _ => (),
106 }
107 }
108 out.push('\n');
109 }
110 _ => {
111 writeln!(out, "{}", format!("+{x}").color(Green));
112 }
113 };
114 }
115 }
116 }
117
118 out.push('\n');
120
121 out
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127 use owo_colors::AnsiColors::{Red, Yellow};
128
129 #[test]
130 fn test_color_output() {
131 let old_str = " Hello你好 ";
132 let new_str = "Hallo 你好";
133
134 let diff = diff_lines_with_err_color(old_str, new_str, Red, on_color);
135 assert_eq!(
136 "\u{1b}[31m-\u{1b}[39m\u{1b}[30;41m \u{1b}[0m\u{1b}[31mH\u{1b}[39m\u{1b}[30;41me\u{1b}[0m\u{1b}[31ml\u{1b}[39m\u{1b}[31ml\u{1b}[39m\u{1b}[31mo\u{1b}[39m\u{1b}[31m你\u{1b}[39m\u{1b}[31m好\u{1b}[39m\u{1b}[30;41m \u{1b}[0m\n\u{1b}[32m+\u{1b}[39m\u{1b}[32mH\u{1b}[39m\u{1b}[30;42ma\u{1b}[0m\u{1b}[32ml\u{1b}[39m\u{1b}[32ml\u{1b}[39m\u{1b}[32mo\u{1b}[39m\u{1b}[30;42m \u{1b}[0m\u{1b}[32m你\u{1b}[39m\u{1b}[32m好\u{1b}[39m\n\n",
137 diff
138 );
139
140 let diff = diff_lines_with_err_color(old_str, new_str, Yellow, on_color);
141 assert_eq!(
142 "\u{1b}[33m-\u{1b}[39m\u{1b}[30;43m \u{1b}[0m\u{1b}[33mH\u{1b}[39m\u{1b}[30;43me\u{1b}[0m\u{1b}[33ml\u{1b}[39m\u{1b}[33ml\u{1b}[39m\u{1b}[33mo\u{1b}[39m\u{1b}[33m你\u{1b}[39m\u{1b}[33m好\u{1b}[39m\u{1b}[30;43m \u{1b}[0m\n\u{1b}[32m+\u{1b}[39m\u{1b}[32mH\u{1b}[39m\u{1b}[30;42ma\u{1b}[0m\u{1b}[32ml\u{1b}[39m\u{1b}[32ml\u{1b}[39m\u{1b}[32mo\u{1b}[39m\u{1b}[30;42m \u{1b}[0m\u{1b}[32m你\u{1b}[39m\u{1b}[32m好\u{1b}[39m\n\n",
143 diff
144 );
145
146 let diff = diff_lines_with_err_color(old_str, new_str, Red, on_color_transparent);
147 assert_eq!("\u{1b}[31m-\u{1b}[39m\u{1b}[31m \u{1b}[39m\u{1b}[31mH\u{1b}[39m\u{1b}[31me\u{1b}[39m\u{1b}[31ml\u{1b}[39m\u{1b}[31ml\u{1b}[39m\u{1b}[31mo\u{1b}[39m\u{1b}[31m你\u{1b}[39m\u{1b}[31m好\u{1b}[39m\u{1b}[31m \u{1b}[39m\n\u{1b}[32m+\u{1b}[39m\u{1b}[32mH\u{1b}[39m\u{1b}[32ma\u{1b}[39m\u{1b}[32ml\u{1b}[39m\u{1b}[32ml\u{1b}[39m\u{1b}[32mo\u{1b}[39m\u{1b}[32m \u{1b}[39m\u{1b}[32m你\u{1b}[39m\u{1b}[32m好\u{1b}[39m\n\n", diff);
148
149 let diff = diff_lines_with_err_color(old_str, new_str, Yellow, on_color_transparent);
150 assert_eq!("\u{1b}[33m-\u{1b}[39m\u{1b}[33m \u{1b}[39m\u{1b}[33mH\u{1b}[39m\u{1b}[33me\u{1b}[39m\u{1b}[33ml\u{1b}[39m\u{1b}[33ml\u{1b}[39m\u{1b}[33mo\u{1b}[39m\u{1b}[33m你\u{1b}[39m\u{1b}[33m好\u{1b}[39m\u{1b}[33m \u{1b}[39m\n\u{1b}[32m+\u{1b}[39m\u{1b}[32mH\u{1b}[39m\u{1b}[32ma\u{1b}[39m\u{1b}[32ml\u{1b}[39m\u{1b}[32ml\u{1b}[39m\u{1b}[32mo\u{1b}[39m\u{1b}[32m \u{1b}[39m\u{1b}[32m你\u{1b}[39m\u{1b}[32m好\u{1b}[39m\n\n", diff);
151 }
152}