diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:06:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:06:31 +0000 |
commit | 2ff14448863ac1a1dd9533461708e29aae170c2d (patch) | |
tree | 85b9fea2bbfe3f06473cfa381eed11f273b57c5c /vendor/pretty_assertions-0.7.2/src/printer.rs | |
parent | Adding debian version 1.64.0+dfsg1-1. (diff) | |
download | rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.tar.xz rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.zip |
Adding debian version 1.65.0+dfsg1-2.debian/1.65.0+dfsg1-2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/pretty_assertions-0.7.2/src/printer.rs')
-rw-r--r-- | vendor/pretty_assertions-0.7.2/src/printer.rs | 474 |
1 files changed, 0 insertions, 474 deletions
diff --git a/vendor/pretty_assertions-0.7.2/src/printer.rs b/vendor/pretty_assertions-0.7.2/src/printer.rs deleted file mode 100644 index 172b1ed6c..000000000 --- a/vendor/pretty_assertions-0.7.2/src/printer.rs +++ /dev/null @@ -1,474 +0,0 @@ -use ansi_term::{ - Colour::{Fixed, Green, Red}, - Style, -}; -use std::fmt; - -macro_rules! paint { - ($f:expr, $colour:expr, $fmt:expr, $($args:tt)*) => ( - write!($f, "{}", $colour.paint(format!($fmt, $($args)*))) - ) -} - -const SIGN_RIGHT: char = '>'; // + > → -const SIGN_LEFT: char = '<'; // - < ← - -/// Present the diff output for two mutliline strings in a pretty, colorised manner. -pub(crate) fn write_header(f: &mut fmt::Formatter) -> fmt::Result { - writeln!( - f, - "{} {} / {} :", - Style::new().bold().paint("Diff"), - Red.paint(format!("{} left", SIGN_LEFT)), - Green.paint(format!("right {}", SIGN_RIGHT)) - ) -} - -/// Delay formatting this deleted chunk until later. -/// -/// It can be formatted as a whole chunk by calling `flush`, or the inner value -/// obtained with `take` for further processing. -#[derive(Default)] -struct LatentDeletion<'a> { - // The most recent deleted line we've seen - value: Option<&'a str>, - // The number of deleted lines we've seen, including the current value - count: usize, -} - -impl<'a> LatentDeletion<'a> { - /// Set the chunk value. - fn set(&mut self, value: &'a str) { - self.value = Some(value); - self.count += 1; - } - - /// Take the underlying chunk value, if it's suitable for inline diffing. - /// - /// If there is no value of we've seen more than one line, return `None`. - fn take(&mut self) -> Option<&'a str> { - if self.count == 1 { - self.value.take() - } else { - None - } - } - - /// If a value is set, print it as a whole chunk, using the given formatter. - /// - /// If a value is not set, reset the count to zero (as we've called `flush` twice, - /// without seeing another deletion. Therefore the line in the middle was something else). - fn flush<TWrite: fmt::Write>(&mut self, f: &mut TWrite) -> fmt::Result { - if let Some(value) = self.value { - paint!(f, Red, "{}{}", SIGN_LEFT, value)?; - writeln!(f)?; - self.value = None; - } else { - self.count = 0; - } - - Ok(()) - } -} - -// Adapted from: -// https://github.com/johannhof/difference.rs/blob/c5749ad7d82aa3d480c15cb61af9f6baa08f116f/examples/github-style.rs -// Credits johannhof (MIT License) - -/// Present the diff output for two mutliline strings in a pretty, colorised manner. -pub(crate) fn write_lines<TWrite: fmt::Write>( - f: &mut TWrite, - left: &str, - right: &str, -) -> fmt::Result { - let diff = ::diff::lines(left, right); - - let mut changes = diff.into_iter().peekable(); - let mut previous_deletion = LatentDeletion::default(); - - while let Some(change) = changes.next() { - match (change, changes.peek()) { - // If the text is unchanged, just print it plain - (::diff::Result::Both(value, _), _) => { - previous_deletion.flush(f)?; - writeln!(f, " {}", value)?; - } - // Defer any deletions to next loop - (::diff::Result::Left(deleted), _) => { - previous_deletion.flush(f)?; - previous_deletion.set(deleted); - } - // Underlying diff library should never return this sequence - (::diff::Result::Right(_), Some(::diff::Result::Left(_))) => { - panic!("insertion followed by deletion"); - } - // If we're being followed by more insertions, don't inline diff - (::diff::Result::Right(inserted), Some(::diff::Result::Right(_))) => { - previous_deletion.flush(f)?; - paint!(f, Green, "{}{}", SIGN_RIGHT, inserted)?; - writeln!(f)?; - } - // Otherwise, check if we need to inline diff with the previous line (if it was a deletion) - (::diff::Result::Right(inserted), _) => { - if let Some(deleted) = previous_deletion.take() { - write_inline_diff(f, deleted, inserted)?; - } else { - previous_deletion.flush(f)?; - paint!(f, Green, "{}{}", SIGN_RIGHT, inserted)?; - writeln!(f)?; - } - } - }; - } - - previous_deletion.flush(f)?; - Ok(()) -} - -/// Group character styling for an inline diff, to prevent wrapping each single -/// character in terminal styling codes. -/// -/// Styles are applied automatically each time a new style is given in `write_with_style`. -struct InlineWriter<'a, Writer> { - f: &'a mut Writer, - style: Style, -} - -impl<'a, Writer> InlineWriter<'a, Writer> -where - Writer: fmt::Write, -{ - fn new(f: &'a mut Writer) -> Self { - InlineWriter { - f, - style: Style::new(), - } - } - - /// Push a new character into the buffer, specifying the style it should be written in. - fn write_with_style(&mut self, c: &char, style: Style) -> fmt::Result { - // If the style is the same as previously, just write character - if style == self.style { - write!(self.f, "{}", c)?; - } else { - // Close out previous style - write!(self.f, "{}", self.style.suffix())?; - - // Store new style and start writing it - write!(self.f, "{}{}", style.prefix(), c)?; - self.style = style; - } - Ok(()) - } - - /// Finish any existing style and reset to default state. - fn finish(&mut self) -> fmt::Result { - // Close out previous style - writeln!(self.f, "{}", self.style.suffix())?; - self.style = Default::default(); - Ok(()) - } -} - -/// Format a single line to show an inline diff of the two strings given. -/// -/// The given strings should not have a trailing newline. -/// -/// The output of this function will be two lines, each with a trailing newline. -fn write_inline_diff<TWrite: fmt::Write>(f: &mut TWrite, left: &str, right: &str) -> fmt::Result { - let diff = ::diff::chars(left, right); - let mut writer = InlineWriter::new(f); - - // Print the left string on one line, with differences highlighted - let light = Red.into(); - let heavy = Red.on(Fixed(52)).bold(); - writer.write_with_style(&SIGN_LEFT, light)?; - for change in diff.iter() { - match change { - ::diff::Result::Both(value, _) => writer.write_with_style(value, light)?, - ::diff::Result::Left(value) => writer.write_with_style(value, heavy)?, - _ => (), - } - } - writer.finish()?; - - // Print the right string on one line, with differences highlighted - let light = Green.into(); - let heavy = Green.on(Fixed(22)).bold(); - writer.write_with_style(&SIGN_RIGHT, light)?; - for change in diff.iter() { - match change { - ::diff::Result::Both(value, _) => writer.write_with_style(value, light)?, - ::diff::Result::Right(value) => writer.write_with_style(value, heavy)?, - _ => (), - } - } - writer.finish() -} - -#[cfg(test)] -mod test { - use super::*; - - // ANSI terminal codes used in our outputs. - // - // Interpolate these into test strings to make expected values easier to read. - const RED_LIGHT: &str = "\u{1b}[31m"; - const GREEN_LIGHT: &str = "\u{1b}[32m"; - const RED_HEAVY: &str = "\u{1b}[1;48;5;52;31m"; - const GREEN_HEAVY: &str = "\u{1b}[1;48;5;22;32m"; - const RESET: &str = "\u{1b}[0m"; - - /// Given that both of our diff printing functions have the same - /// type signature, we can reuse the same test code for them. - /// - /// This could probably be nicer with traits! - fn check_printer<TPrint>(printer: TPrint, left: &str, right: &str, expected: &str) - where - TPrint: Fn(&mut String, &str, &str) -> fmt::Result, - { - let mut actual = String::new(); - printer(&mut actual, left, right).expect("printer function failed"); - - println!( - "## left ##\n\ - {}\n\ - ## right ##\n\ - {}\n\ - ## actual diff ##\n\ - {}\n\ - ## expected diff ##\n\ - {}", - left, right, actual, expected - ); - assert_eq!(actual, expected); - } - - #[test] - fn write_inline_diff_empty() { - let left = ""; - let right = ""; - let expected = format!( - "{red_light}<{reset}\n\ - {green_light}>{reset}\n", - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - reset = RESET, - ); - - check_printer(write_inline_diff, left, right, &expected); - } - - #[test] - fn write_inline_diff_added() { - let left = ""; - let right = "polymerase"; - let expected = format!( - "{red_light}<{reset}\n\ - {green_light}>{reset}{green_heavy}polymerase{reset}\n", - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - green_heavy = GREEN_HEAVY, - reset = RESET, - ); - - check_printer(write_inline_diff, left, right, &expected); - } - - #[test] - fn write_inline_diff_removed() { - let left = "polyacrylamide"; - let right = ""; - let expected = format!( - "{red_light}<{reset}{red_heavy}polyacrylamide{reset}\n\ - {green_light}>{reset}\n", - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - red_heavy = RED_HEAVY, - reset = RESET, - ); - - check_printer(write_inline_diff, left, right, &expected); - } - - #[test] - fn write_inline_diff_changed() { - let left = "polymerase"; - let right = "polyacrylamide"; - let expected = format!( - "{red_light}<poly{reset}{red_heavy}me{reset}{red_light}ra{reset}{red_heavy}s{reset}{red_light}e{reset}\n\ - {green_light}>poly{reset}{green_heavy}ac{reset}{green_light}r{reset}{green_heavy}yl{reset}{green_light}a{reset}{green_heavy}mid{reset}{green_light}e{reset}\n", - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - red_heavy = RED_HEAVY, - green_heavy = GREEN_HEAVY, - reset = RESET, - ); - - check_printer(write_inline_diff, left, right, &expected); - } - - /// If one of our strings is empty, it should not be shown at all in the output. - #[test] - fn write_lines_empty_string() { - let left = ""; - let right = "content"; - let expected = format!( - "{green_light}>content{reset}\n", - green_light = GREEN_LIGHT, - reset = RESET, - ); - - check_printer(write_lines, left, right, &expected); - } - - /// Realistic multiline struct diffing case. - #[test] - fn write_lines_struct() { - let left = r#"Some( - Foo { - lorem: "Hello World!", - ipsum: 42, - dolor: Ok( - "hey", - ), - }, -)"#; - let right = r#"Some( - Foo { - lorem: "Hello Wrold!", - ipsum: 42, - dolor: Ok( - "hey ho!", - ), - }, -)"#; - let expected = format!( - r#" Some( - Foo {{ -{red_light}< lorem: "Hello W{reset}{red_heavy}o{reset}{red_light}rld!",{reset} -{green_light}> lorem: "Hello Wr{reset}{green_heavy}o{reset}{green_light}ld!",{reset} - ipsum: 42, - dolor: Ok( -{red_light}< "hey",{reset} -{green_light}> "hey{reset}{green_heavy} ho!{reset}{green_light}",{reset} - ), - }}, - ) -"#, - red_light = RED_LIGHT, - red_heavy = RED_HEAVY, - green_light = GREEN_LIGHT, - green_heavy = GREEN_HEAVY, - reset = RESET, - ); - - check_printer(write_lines, left, right, &expected); - } - - /// Relistic multiple line chunks - /// - /// We can't support realistic line diffing in large blocks - /// (also, it's unclear how usefult this is) - /// - /// So if we have more than one line in a single removal chunk, disable inline diffing. - #[test] - fn write_lines_multiline_block() { - let left = r#"Proboscis -Cabbage"#; - let right = r#"Probed -Caravaggio"#; - let expected = format!( - r#"{red_light}<Proboscis{reset} -{red_light}<Cabbage{reset} -{green_light}>Probed{reset} -{green_light}>Caravaggio{reset} -"#, - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - reset = RESET, - ); - - check_printer(write_lines, left, right, &expected); - } - - /// Single deletion line, multiple insertions - no inline diffing. - #[test] - fn write_lines_multiline_insert() { - let left = r#"Cabbage"#; - let right = r#"Probed -Caravaggio"#; - let expected = format!( - r#"{red_light}<Cabbage{reset} -{green_light}>Probed{reset} -{green_light}>Caravaggio{reset} -"#, - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - reset = RESET, - ); - - check_printer(write_lines, left, right, &expected); - } - - /// Multiple deletion, single insertion - no inline diffing. - #[test] - fn write_lines_multiline_delete() { - let left = r#"Proboscis -Cabbage"#; - let right = r#"Probed"#; - let expected = format!( - r#"{red_light}<Proboscis{reset} -{red_light}<Cabbage{reset} -{green_light}>Probed{reset} -"#, - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - reset = RESET, - ); - - check_printer(write_lines, left, right, &expected); - } - - /// Regression test for multiline highlighting issue - #[test] - fn write_lines_issue12() { - let left = r#"[ - 0, - 0, - 0, - 128, - 10, - 191, - 5, - 64, -]"#; - let right = r#"[ - 84, - 248, - 45, - 64, -]"#; - let expected = format!( - r#" [ -{red_light}< 0,{reset} -{red_light}< 0,{reset} -{red_light}< 0,{reset} -{red_light}< 128,{reset} -{red_light}< 10,{reset} -{red_light}< 191,{reset} -{red_light}< 5,{reset} -{green_light}> 84,{reset} -{green_light}> 248,{reset} -{green_light}> 45,{reset} - 64, - ] -"#, - red_light = RED_LIGHT, - green_light = GREEN_LIGHT, - reset = RESET, - ); - - check_printer(write_lines, left, right, &expected); - } -} |