debug.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. use std::fmt;
  2. use style::Style;
  3. /// Styles have a special `Debug` implementation that only shows the fields that
  4. /// are set. Fields that haven’t been touched aren’t included in the output.
  5. ///
  6. /// This behaviour gets bypassed when using the alternate formatting mode
  7. /// `format!("{:#?}")`.
  8. ///
  9. /// use ansi_term::Colour::{Red, Blue};
  10. /// assert_eq!("Style { fg(Red), on(Blue), bold, italic }",
  11. /// format!("{:?}", Red.on(Blue).bold().italic()));
  12. impl fmt::Debug for Style {
  13. fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
  14. if fmt.alternate() {
  15. fmt.debug_struct("Style")
  16. .field("foreground", &self.foreground)
  17. .field("background", &self.background)
  18. .field("blink", &self.is_blink)
  19. .field("bold", &self.is_bold)
  20. .field("dimmed", &self.is_dimmed)
  21. .field("hidden", &self.is_hidden)
  22. .field("italic", &self.is_italic)
  23. .field("reverse", &self.is_reverse)
  24. .field("strikethrough", &self.is_strikethrough)
  25. .field("underline", &self.is_underline)
  26. .finish()
  27. }
  28. else if self.is_plain() {
  29. fmt.write_str("Style {}")
  30. }
  31. else {
  32. fmt.write_str("Style { ")?;
  33. let mut written_anything = false;
  34. if let Some(fg) = self.foreground {
  35. if written_anything { fmt.write_str(", ")? }
  36. written_anything = true;
  37. write!(fmt, "fg({:?})", fg)?
  38. }
  39. if let Some(bg) = self.background {
  40. if written_anything { fmt.write_str(", ")? }
  41. written_anything = true;
  42. write!(fmt, "on({:?})", bg)?
  43. }
  44. {
  45. let mut write_flag = |name| {
  46. if written_anything { fmt.write_str(", ")? }
  47. written_anything = true;
  48. fmt.write_str(name)
  49. };
  50. if self.is_blink { write_flag("blink")? }
  51. if self.is_bold { write_flag("bold")? }
  52. if self.is_dimmed { write_flag("dimmed")? }
  53. if self.is_hidden { write_flag("hidden")? }
  54. if self.is_italic { write_flag("italic")? }
  55. if self.is_reverse { write_flag("reverse")? }
  56. if self.is_strikethrough { write_flag("strikethrough")? }
  57. if self.is_underline { write_flag("underline")? }
  58. }
  59. write!(fmt, " }}")
  60. }
  61. }
  62. }
  63. #[cfg(test)]
  64. mod test {
  65. use style::Colour::*;
  66. use style::Style;
  67. fn style() -> Style {
  68. Style::new()
  69. }
  70. macro_rules! test {
  71. ($name: ident: $obj: expr => $result: expr) => {
  72. #[test]
  73. fn $name() {
  74. assert_eq!($result, format!("{:?}", $obj));
  75. }
  76. };
  77. }
  78. test!(empty: style() => "Style {}");
  79. test!(bold: style().bold() => "Style { bold }");
  80. test!(italic: style().italic() => "Style { italic }");
  81. test!(both: style().bold().italic() => "Style { bold, italic }");
  82. test!(red: Red.normal() => "Style { fg(Red) }");
  83. test!(redblue: Red.normal().on(RGB(3, 2, 4)) => "Style { fg(Red), on(RGB(3, 2, 4)) }");
  84. test!(everything:
  85. Red.on(Blue).blink().bold().dimmed().hidden().italic().reverse().strikethrough().underline() =>
  86. "Style { fg(Red), on(Blue), blink, bold, dimmed, hidden, italic, reverse, strikethrough, underline }");
  87. #[test]
  88. fn long_and_detailed() {
  89. extern crate regex;
  90. let expected_debug = "Style { fg(Blue), bold }";
  91. let expected_pretty_repat = r##"(?x)
  92. Style\s+\{\s+
  93. foreground:\s+Some\(\s+
  94. Blue,?\s+
  95. \),\s+
  96. background:\s+None,\s+
  97. blink:\s+false,\s+
  98. bold:\s+true,\s+
  99. dimmed:\s+false,\s+
  100. hidden:\s+false,\s+
  101. italic:\s+false,\s+
  102. reverse:\s+false,\s+
  103. strikethrough:\s+
  104. false,\s+
  105. underline:\s+false,?\s+
  106. \}"##;
  107. let re = regex::Regex::new(expected_pretty_repat).unwrap();
  108. let style = Blue.bold();
  109. let style_fmt_debug = format!("{:?}", style);
  110. let style_fmt_pretty = format!("{:#?}", style);
  111. println!("style_fmt_debug:\n{}", style_fmt_debug);
  112. println!("style_fmt_pretty:\n{}", style_fmt_pretty);
  113. assert_eq!(expected_debug, style_fmt_debug);
  114. assert!(re.is_match(&style_fmt_pretty));
  115. }
  116. }