mz_testdrive/util/
text.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use similar::{ChangeTag, TextDiff};
11use std::io::IsTerminal;
12use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
13
14/// Trims trailing whitespace from each line of `s`.
15pub fn trim_trailing_space(s: &str) -> String {
16    let mut lines: Vec<_> = s.lines().map(|line| line.trim_end()).collect();
17    while lines.last().map_or(false, |l| l.is_empty()) {
18        lines.pop();
19    }
20    lines.join("\n")
21}
22
23/// Prints a colorized line diff of `expected` and `actual`.
24pub fn print_diff(expected: &str, actual: &str) {
25    let color_choice = if std::io::stdout().is_terminal() {
26        ColorChoice::Auto
27    } else {
28        ColorChoice::Never
29    };
30    let mut stdout = StandardStream::stdout(color_choice);
31    let diff = TextDiff::from_lines(expected, actual);
32    println!("--- expected");
33    println!("+++ actual");
34    for op in diff.ops() {
35        for change in diff.iter_changes(op) {
36            let sign = match change.tag() {
37                ChangeTag::Delete => {
38                    let _ = stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)));
39                    "-"
40                }
41                ChangeTag::Insert => {
42                    let _ = stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)));
43                    "+"
44                }
45                ChangeTag::Equal => " ",
46            };
47            print!("{}{}", sign, change);
48            let _ = stdout.reset();
49        }
50    }
51}