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