| use crate::style::Style; |
| use std::fmt; |
| |
| /// Styles have a special `Debug` implementation that only shows the fields that |
| /// are set. Fields that haven’t been touched aren’t included in the output. |
| /// |
| /// This behaviour gets bypassed when using the alternate formatting mode |
| /// `format!("{:#?}")`. |
| /// |
| /// use nu_ansi_term::Color::{Red, Blue}; |
| /// assert_eq!("Style { fg(Red), on(Blue), bold, italic }", |
| /// format!("{:?}", Red.on(Blue).bold().italic())); |
| impl fmt::Debug for Style { |
| fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
| if fmt.alternate() { |
| fmt.debug_struct("Style") |
| .field("foreground", &self.foreground) |
| .field("background", &self.background) |
| .field("blink", &self.is_blink) |
| .field("bold", &self.is_bold) |
| .field("dimmed", &self.is_dimmed) |
| .field("hidden", &self.is_hidden) |
| .field("italic", &self.is_italic) |
| .field("reverse", &self.is_reverse) |
| .field("strikethrough", &self.is_strikethrough) |
| .field("underline", &self.is_underline) |
| .finish() |
| } else if self.is_plain() { |
| fmt.write_str("Style {}") |
| } else { |
| fmt.write_str("Style { ")?; |
| |
| let mut written_anything = false; |
| |
| if let Some(fg) = self.foreground { |
| if written_anything { |
| fmt.write_str(", ")? |
| } |
| written_anything = true; |
| write!(fmt, "fg({:?})", fg)? |
| } |
| |
| if let Some(bg) = self.background { |
| if written_anything { |
| fmt.write_str(", ")? |
| } |
| written_anything = true; |
| write!(fmt, "on({:?})", bg)? |
| } |
| |
| { |
| let mut write_flag = |name| { |
| if written_anything { |
| fmt.write_str(", ")? |
| } |
| written_anything = true; |
| fmt.write_str(name) |
| }; |
| |
| if self.is_blink { |
| write_flag("blink")? |
| } |
| if self.is_bold { |
| write_flag("bold")? |
| } |
| if self.is_dimmed { |
| write_flag("dimmed")? |
| } |
| if self.is_hidden { |
| write_flag("hidden")? |
| } |
| if self.is_italic { |
| write_flag("italic")? |
| } |
| if self.is_reverse { |
| write_flag("reverse")? |
| } |
| if self.is_strikethrough { |
| write_flag("strikethrough")? |
| } |
| if self.is_underline { |
| write_flag("underline")? |
| } |
| } |
| |
| write!(fmt, " }}") |
| } |
| } |
| } |
| |
| #[cfg(test)] |
| mod test { |
| use crate::style::Color::*; |
| use crate::style::Style; |
| |
| fn style() -> Style { |
| Style::new() |
| } |
| |
| macro_rules! test { |
| ($name: ident: $obj: expr => $result: expr) => { |
| #[test] |
| fn $name() { |
| assert_eq!($result, format!("{:?}", $obj)); |
| } |
| }; |
| } |
| |
| test!(empty: style() => "Style {}"); |
| test!(bold: style().bold() => "Style { bold }"); |
| test!(italic: style().italic() => "Style { italic }"); |
| test!(both: style().bold().italic() => "Style { bold, italic }"); |
| |
| test!(red: Red.normal() => "Style { fg(Red) }"); |
| test!(redblue: Red.normal().on(Rgb(3, 2, 4)) => "Style { fg(Red), on(Rgb(3, 2, 4)) }"); |
| |
| test!(everything: |
| Red.on(Blue).blink().bold().dimmed().hidden().italic().reverse().strikethrough().underline() => |
| "Style { fg(Red), on(Blue), blink, bold, dimmed, hidden, italic, reverse, strikethrough, underline }"); |
| |
| #[test] |
| fn long_and_detailed() { |
| extern crate regex; |
| let expected_debug = "Style { fg(Blue), bold }"; |
| let expected_pretty_repat = r##"(?x) |
| Style\s+\{\s+ |
| foreground:\s+Some\(\s+ |
| Blue,?\s+ |
| \),\s+ |
| background:\s+None,\s+ |
| blink:\s+false,\s+ |
| bold:\s+true,\s+ |
| dimmed:\s+false,\s+ |
| hidden:\s+false,\s+ |
| italic:\s+false,\s+ |
| reverse:\s+false,\s+ |
| strikethrough:\s+ |
| false,\s+ |
| underline:\s+false,?\s+ |
| \}"##; |
| let re = regex::Regex::new(expected_pretty_repat).unwrap(); |
| |
| let style = Blue.bold(); |
| let style_fmt_debug = format!("{:?}", style); |
| let style_fmt_pretty = format!("{:#?}", style); |
| println!("style_fmt_debug:\n{}", style_fmt_debug); |
| println!("style_fmt_pretty:\n{}", style_fmt_pretty); |
| |
| assert_eq!(expected_debug, style_fmt_debug); |
| assert!(re.is_match(&style_fmt_pretty)); |
| } |
| } |