11// Code for creating styled buffers
22
33use crate :: snippet:: { Style , StyledString } ;
4- use std:: iter;
54
65#[ derive( Debug ) ]
76pub struct StyledBuffer {
8- text : Vec < Vec < char > > ,
9- styles : Vec < Vec < Style > > ,
7+ text : Vec < Vec < StyledChar > > ,
8+ }
9+
10+ #[ derive( Debug ) ]
11+ struct StyledChar {
12+ chr : char ,
13+ style : Style ,
14+ }
15+
16+ impl StyledChar {
17+ fn new ( chr : char , style : Style ) -> Self {
18+ StyledChar { chr, style }
19+ }
1020}
1121
1222impl StyledBuffer {
1323 pub fn new ( ) -> StyledBuffer {
14- StyledBuffer { text : vec ! [ ] , styles : vec ! [ ] }
24+ StyledBuffer { text : vec ! [ ] }
1525 }
1626
1727 pub fn render ( & self ) -> Vec < Vec < StyledString > > {
1828 // Tabs are assumed to have been replaced by spaces in calling code.
19- debug_assert ! ( self . text. iter( ) . all( |r| !r. contains ( & '\t' ) ) ) ;
29+ debug_assert ! ( self . text. iter( ) . all( |r| !r. iter ( ) . any ( |sc| sc . chr == '\t' ) ) ) ;
2030
2131 let mut output: Vec < Vec < StyledString > > = vec ! [ ] ;
2232 let mut styled_vec: Vec < StyledString > = vec ! [ ] ;
2333
24- for ( row , row_style ) in iter :: zip ( & self . text , & self . styles ) {
34+ for styled_row in & self . text {
2535 let mut current_style = Style :: NoStyle ;
2636 let mut current_text = String :: new ( ) ;
2737
28- for ( & c , & s ) in iter :: zip ( row , row_style ) {
29- if s != current_style {
38+ for sc in styled_row {
39+ if sc . style != current_style {
3040 if !current_text. is_empty ( ) {
3141 styled_vec. push ( StyledString { text : current_text, style : current_style } ) ;
3242 }
33- current_style = s ;
43+ current_style = sc . style ;
3444 current_text = String :: new ( ) ;
3545 }
36- current_text. push ( c ) ;
46+ current_text. push ( sc . chr ) ;
3747 }
3848 if !current_text. is_empty ( ) {
3949 styled_vec. push ( StyledString { text : current_text, style : current_style } ) ;
@@ -51,24 +61,20 @@ impl StyledBuffer {
5161 fn ensure_lines ( & mut self , line : usize ) {
5262 while line >= self . text . len ( ) {
5363 self . text . push ( vec ! [ ] ) ;
54- self . styles . push ( vec ! [ ] ) ;
5564 }
5665 }
5766
5867 pub fn putc ( & mut self , line : usize , col : usize , chr : char , style : Style ) {
5968 self . ensure_lines ( line) ;
6069 if col < self . text [ line] . len ( ) {
61- self . text [ line] [ col] = chr;
62- self . styles [ line] [ col] = style;
70+ self . text [ line] [ col] = StyledChar :: new ( chr, style) ;
6371 } else {
6472 let mut i = self . text [ line] . len ( ) ;
6573 while i < col {
66- self . text [ line] . push ( ' ' ) ;
67- self . styles [ line] . push ( Style :: NoStyle ) ;
74+ self . text [ line] . push ( StyledChar :: new ( ' ' , Style :: NoStyle ) ) ;
6875 i += 1 ;
6976 }
70- self . text [ line] . push ( chr) ;
71- self . styles [ line] . push ( style) ;
77+ self . text [ line] . push ( StyledChar :: new ( chr, style) ) ;
7278 }
7379 }
7480
@@ -86,8 +92,7 @@ impl StyledBuffer {
8692
8793 // Push the old content over to make room for new content
8894 for _ in 0 ..string_len {
89- self . styles [ line] . insert ( 0 , Style :: NoStyle ) ;
90- self . text [ line] . insert ( 0 , ' ' ) ;
95+ self . text [ line] . insert ( 0 , StyledChar :: new ( ' ' , Style :: NoStyle ) ) ;
9196 }
9297
9398 self . puts ( line, 0 , string, style) ;
@@ -120,8 +125,8 @@ impl StyledBuffer {
120125 }
121126
122127 pub fn set_style ( & mut self , line : usize , col : usize , style : Style , overwrite : bool ) {
123- if let Some ( ref mut line) = self . styles . get_mut ( line) {
124- if let Some ( s ) = line. get_mut ( col) {
128+ if let Some ( ref mut line) = self . text . get_mut ( line) {
129+ if let Some ( StyledChar { style : s , .. } ) = line. get_mut ( col) {
125130 if * s == Style :: NoStyle || * s == Style :: Quotation || overwrite {
126131 * s = style;
127132 }
0 commit comments