@@ -36,9 +36,9 @@ pub const RESET_STYLES: CharacterStyles = CharacterStyles {
36
36
styled_underlines_enabled : false ,
37
37
} ;
38
38
39
- // Have to manually write this out because Default::default
40
- // is not a const fn
41
- const DEFAULT_STYLES : CharacterStyles = CharacterStyles {
39
+ // Prefer to use RcCharacterStyles::default() where it makes sense
40
+ // as it will reduce memory usage
41
+ pub const DEFAULT_STYLES : CharacterStyles = CharacterStyles {
42
42
foreground : None ,
43
43
background : None ,
44
44
underline_color : None ,
@@ -55,6 +55,11 @@ const DEFAULT_STYLES: CharacterStyles = CharacterStyles {
55
55
styled_underlines_enabled : false ,
56
56
} ;
57
57
58
+ thread_local ! {
59
+ static RC_DEFAULT_STYLES : RcCharacterStyles =
60
+ RcCharacterStyles :: Rc ( Rc :: new( DEFAULT_STYLES ) ) ;
61
+ }
62
+
58
63
#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
59
64
pub enum AnsiCode {
60
65
On ,
@@ -149,32 +154,36 @@ impl NamedColor {
149
154
}
150
155
}
151
156
152
- #[ derive( Clone , Debug , Default , PartialEq ) ]
157
+ // This enum carefully only has two variants so
158
+ // enum niche optimisations can keep it to 8 bytes
159
+ #[ derive( Clone , Debug , PartialEq ) ]
153
160
pub enum RcCharacterStyles {
154
- #[ default]
155
- Default ,
156
161
Reset ,
157
162
Rc ( Rc < CharacterStyles > ) ,
158
163
}
164
+ const _: [ ( ) ; 8 ] = [ ( ) ; std:: mem:: size_of :: < RcCharacterStyles > ( ) ] ;
159
165
160
166
impl From < CharacterStyles > for RcCharacterStyles {
161
167
fn from ( styles : CharacterStyles ) -> Self {
162
- if styles == DEFAULT_STYLES {
163
- RcCharacterStyles :: Default
164
- } else if styles == RESET_STYLES {
168
+ if styles == RESET_STYLES {
165
169
RcCharacterStyles :: Reset
166
170
} else {
167
171
RcCharacterStyles :: Rc ( Rc :: new ( styles) )
168
172
}
169
173
}
170
174
}
171
175
176
+ impl Default for RcCharacterStyles {
177
+ fn default ( ) -> Self {
178
+ RC_DEFAULT_STYLES . with ( |s| s. clone ( ) )
179
+ }
180
+ }
181
+
172
182
impl std:: ops:: Deref for RcCharacterStyles {
173
183
type Target = CharacterStyles ;
174
184
175
185
fn deref ( & self ) -> & Self :: Target {
176
186
match self {
177
- RcCharacterStyles :: Default => & DEFAULT_STYLES ,
178
187
RcCharacterStyles :: Reset => & RESET_STYLES ,
179
188
RcCharacterStyles :: Rc ( styles) => & * styles,
180
189
}
@@ -189,6 +198,10 @@ impl Display for RcCharacterStyles {
189
198
}
190
199
191
200
impl RcCharacterStyles {
201
+ pub fn reset ( ) -> Self {
202
+ Self :: Reset
203
+ }
204
+
192
205
pub fn update ( & mut self , f : impl FnOnce ( & mut CharacterStyles ) ) {
193
206
let mut styles: CharacterStyles = * * self ;
194
207
f ( & mut styles) ;
@@ -214,12 +227,6 @@ pub struct CharacterStyles {
214
227
pub styled_underlines_enabled : bool ,
215
228
}
216
229
217
- impl Default for CharacterStyles {
218
- fn default ( ) -> Self {
219
- DEFAULT_STYLES
220
- }
221
- }
222
-
223
230
impl PartialEq for CharacterStyles {
224
231
fn eq ( & self , other : & Self ) -> bool {
225
232
self . foreground == other. foreground
@@ -239,9 +246,6 @@ impl PartialEq for CharacterStyles {
239
246
}
240
247
241
248
impl CharacterStyles {
242
- pub fn new ( ) -> Self {
243
- Self :: default ( )
244
- }
245
249
pub fn foreground ( mut self , foreground_code : Option < AnsiCode > ) -> Self {
246
250
self . foreground = foreground_code;
247
251
self
@@ -329,7 +333,7 @@ impl CharacterStyles {
329
333
330
334
// create diff from all changed styles
331
335
let mut diff =
332
- CharacterStyles :: new ( ) . enable_styled_underlines ( self . styled_underlines_enabled ) ;
336
+ DEFAULT_STYLES . enable_styled_underlines ( self . styled_underlines_enabled ) ;
333
337
334
338
if self . foreground != new_styles. foreground {
335
339
diff. foreground = new_styles. foreground ;
@@ -388,7 +392,7 @@ impl CharacterStyles {
388
392
}
389
393
Some ( diff)
390
394
}
391
- pub fn reset_all ( & mut self ) {
395
+ fn reset_all ( & mut self ) {
392
396
self . foreground = Some ( AnsiCode :: Reset ) ;
393
397
self . background = Some ( AnsiCode :: Reset ) ;
394
398
self . underline_color = Some ( AnsiCode :: Reset ) ;
@@ -917,6 +921,9 @@ pub struct TerminalCharacter {
917
921
pub styles : RcCharacterStyles ,
918
922
width : u8 ,
919
923
}
924
+ // This size has significant memory and CPU implications for long lines,
925
+ // be careful about allowing it to grow
926
+ const _: [ ( ) ; 16 ] = [ ( ) ; std:: mem:: size_of :: < TerminalCharacter > ( ) ] ;
920
927
921
928
impl TerminalCharacter {
922
929
#[ inline]
0 commit comments