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