use std::fmt; use style::Style; /// 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 ansi_term::Colour::{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 style::Colour::*; use 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)); } }