nu_ansi_term/
difference.rs1use super::Style;
2
3#[derive(PartialEq, Clone, Copy, Debug)]
6pub enum Difference {
7 ExtraStyles(Style),
10
11 Reset,
14
15 Empty,
18}
19
20impl Difference {
21 pub fn between(first: &Style, next: &Style) -> Difference {
36 use self::Difference::*;
37
38 if first == next {
43 return Empty;
44 }
45
46 if first.is_bold && !next.is_bold {
48 return Reset;
49 }
50
51 if first.is_dimmed && !next.is_dimmed {
52 return Reset;
53 }
54
55 if first.is_italic && !next.is_italic {
56 return Reset;
57 }
58
59 if first.is_underline && !next.is_underline {
61 return Reset;
62 }
63
64 if first.is_blink && !next.is_blink {
65 return Reset;
66 }
67
68 if first.is_reverse && !next.is_reverse {
69 return Reset;
70 }
71
72 if first.is_hidden && !next.is_hidden {
73 return Reset;
74 }
75
76 if first.is_strikethrough && !next.is_strikethrough {
77 return Reset;
78 }
79
80 if first.foreground.is_some() && next.foreground.is_none() {
82 return Reset;
83 }
84
85 if first.background.is_some() && next.background.is_none() {
87 return Reset;
88 }
89
90 let mut extra_styles = Style::default();
91
92 if first.is_bold != next.is_bold {
93 extra_styles.is_bold = true;
94 }
95
96 if first.is_dimmed != next.is_dimmed {
97 extra_styles.is_dimmed = true;
98 }
99
100 if first.is_italic != next.is_italic {
101 extra_styles.is_italic = true;
102 }
103
104 if first.is_underline != next.is_underline {
105 extra_styles.is_underline = true;
106 }
107
108 if first.is_blink != next.is_blink {
109 extra_styles.is_blink = true;
110 }
111
112 if first.is_reverse != next.is_reverse {
113 extra_styles.is_reverse = true;
114 }
115
116 if first.is_hidden != next.is_hidden {
117 extra_styles.is_hidden = true;
118 }
119
120 if first.is_strikethrough != next.is_strikethrough {
121 extra_styles.is_strikethrough = true;
122 }
123
124 if first.foreground != next.foreground {
125 extra_styles.foreground = next.foreground;
126 }
127
128 if first.background != next.background {
129 extra_styles.background = next.background;
130 }
131
132 ExtraStyles(extra_styles)
133 }
134}
135
136#[cfg(test)]
137mod test {
138 use super::Difference::*;
139 use super::*;
140 use crate::style::Color::*;
141 use crate::style::Style;
142
143 fn style() -> Style {
144 Style::new()
145 }
146
147 macro_rules! test {
148 ($name: ident: $first: expr; $next: expr => $result: expr) => {
149 #[test]
150 fn $name() {
151 assert_eq!($result, Difference::between(&$first, &$next));
152 }
153 };
154 }
155
156 test!(nothing: Green.normal(); Green.normal() => Empty);
157 test!(uppercase: Green.normal(); Green.bold() => ExtraStyles(style().bold()));
158 test!(lowercase: Green.bold(); Green.normal() => Reset);
159 test!(nothing2: Green.bold(); Green.bold() => Empty);
160
161 test!(color_change: Red.normal(); Blue.normal() => ExtraStyles(Blue.normal()));
162
163 test!(addition_of_blink: style(); style().blink() => ExtraStyles(style().blink()));
164 test!(addition_of_dimmed: style(); style().dimmed() => ExtraStyles(style().dimmed()));
165 test!(addition_of_hidden: style(); style().hidden() => ExtraStyles(style().hidden()));
166 test!(addition_of_reverse: style(); style().reverse() => ExtraStyles(style().reverse()));
167 test!(addition_of_strikethrough: style(); style().strikethrough() => ExtraStyles(style().strikethrough()));
168
169 test!(removal_of_strikethrough: style().strikethrough(); style() => Reset);
170 test!(removal_of_reverse: style().reverse(); style() => Reset);
171 test!(removal_of_hidden: style().hidden(); style() => Reset);
172 test!(removal_of_dimmed: style().dimmed(); style() => Reset);
173 test!(removal_of_blink: style().blink(); style() => Reset);
174}