1
1
use crate :: {
2
- messages:: { Message , MessageCopyState , MessageLevel } ,
2
+ messages:: { Envelope , Message , MessageCopyState , MessageLevel } ,
3
3
progress:: { self , Value } ,
4
4
unit, Root , Throughput ,
5
5
} ;
@@ -13,7 +13,7 @@ use unicode_width::UnicodeWidthStr;
13
13
#[ derive( Default ) ]
14
14
pub struct State {
15
15
tree : Vec < ( progress:: Key , progress:: Task ) > ,
16
- messages : Vec < Message > ,
16
+ messages : Vec < Envelope > ,
17
17
for_next_copy : Option < MessageCopyState > ,
18
18
/// The size of the message origin, tracking the terminal height so things potentially off screen don't influence width anymore.
19
19
message_origin_size : VecDeque < usize > ,
@@ -52,47 +52,57 @@ fn messages(
52
52
}
53
53
let mut tokens: Vec < ANSIString < ' _ > > = Vec :: with_capacity ( 6 ) ;
54
54
let mut current_maximum = state. message_origin_size . iter ( ) . max ( ) . cloned ( ) . unwrap_or ( 0 ) ;
55
- for Message {
56
- time,
57
- level,
58
- origin,
59
- message,
60
- } in & state. messages
61
- {
55
+ for envelope in & state. messages {
62
56
tokens. clear ( ) ;
63
57
let blocks_drawn_during_previous_tick = state. blocks_per_line . pop_front ( ) . unwrap_or ( 0 ) ;
64
- let message_block_len = origin. width ( ) ;
65
- current_maximum = current_maximum. max ( message_block_len) ;
66
- if state. message_origin_size . len ( ) == max_height {
67
- state. message_origin_size . pop_front ( ) ;
68
- }
69
- state. message_origin_size . push_back ( message_block_len) ;
70
58
71
- let color = to_color ( * level) ;
72
- tokens. push ( " " . into ( ) ) ;
73
- if timestamp {
74
- tokens. push (
75
- brush
76
- . style ( color. dimmed ( ) . on ( Color :: Yellow ) )
77
- . paint ( crate :: time:: format_time_for_messages ( * time) ) ,
78
- ) ;
79
- tokens. push ( Style :: default ( ) . paint ( " " ) ) ;
80
- } else {
81
- tokens. push ( "" . into ( ) ) ;
59
+ match envelope {
60
+ Envelope :: RawMessage ( content) => {
61
+ // RawMessages have already been split into single lines without newlines appended,
62
+ // and so can be rendered directly as ANSIStrings.
63
+ tokens. push ( ANSIString :: from ( content) )
64
+ }
65
+ Envelope :: Message ( Message {
66
+ time,
67
+ level,
68
+ origin,
69
+ message,
70
+ } ) => {
71
+ let message_block_len = origin. width ( ) ;
72
+ current_maximum = current_maximum. max ( message_block_len) ;
73
+ if state. message_origin_size . len ( ) == max_height {
74
+ state. message_origin_size . pop_front ( ) ;
75
+ }
76
+ state. message_origin_size . push_back ( message_block_len) ;
77
+
78
+ let color = to_color ( * level) ;
79
+ tokens. push ( " " . into ( ) ) ;
80
+ if timestamp {
81
+ tokens. push (
82
+ brush
83
+ . style ( color. dimmed ( ) . on ( Color :: Yellow ) )
84
+ . paint ( crate :: time:: format_time_for_messages ( * time) ) ,
85
+ ) ;
86
+ tokens. push ( Style :: default ( ) . paint ( " " ) ) ;
87
+ } else {
88
+ tokens. push ( "" . into ( ) ) ;
89
+ } ;
90
+ tokens. push ( brush. style ( Style :: default ( ) . dimmed ( ) ) . paint ( format ! (
91
+ "{:>fill_size$}{}" ,
92
+ "" ,
93
+ origin,
94
+ fill_size = current_maximum - message_block_len,
95
+ ) ) ) ;
96
+ tokens. push ( " " . into ( ) ) ;
97
+ tokens. push ( brush. style ( color. bold ( ) ) . paint ( message) ) ;
98
+ }
82
99
} ;
83
- tokens. push ( brush. style ( Style :: default ( ) . dimmed ( ) ) . paint ( format ! (
84
- "{:>fill_size$}{}" ,
85
- "" ,
86
- origin,
87
- fill_size = current_maximum - message_block_len,
88
- ) ) ) ;
89
- tokens. push ( " " . into ( ) ) ;
90
- tokens. push ( brush. style ( color. bold ( ) ) . paint ( message) ) ;
100
+
91
101
let message_block_count = block_count_sans_ansi_codes ( & tokens) ;
92
102
write ! ( out, "{}" , ANSIStrings ( tokens. as_slice( ) ) ) ?;
93
103
94
104
if blocks_drawn_during_previous_tick > message_block_count {
95
- newline_with_overdraw ( out, & tokens , blocks_drawn_during_previous_tick) ?;
105
+ newline_with_overdraw ( out, message_block_count , blocks_drawn_during_previous_tick) ?;
96
106
} else {
97
107
writeln ! ( out) ?;
98
108
}
@@ -161,7 +171,8 @@ pub fn all(
161
171
) ;
162
172
write ! ( out, "{}" , ANSIStrings ( tokens. as_slice( ) ) ) ?;
163
173
164
- * * blocks_in_last_iteration = newline_with_overdraw ( out, & tokens, * * blocks_in_last_iteration) ?;
174
+ * * blocks_in_last_iteration =
175
+ newline_with_overdraw ( out, block_count_sans_ansi_codes ( & tokens) , * * blocks_in_last_iteration) ?;
165
176
}
166
177
if let Some ( tp) = state. throughput . as_mut ( ) {
167
178
tp. reconcile ( & state. tree ) ;
@@ -186,10 +197,9 @@ pub fn all(
186
197
/// Must be called directly after `tokens` were drawn, without newline. Takes care of adding the newline.
187
198
fn newline_with_overdraw (
188
199
out : & mut impl io:: Write ,
189
- tokens : & [ ANSIString < ' _ > ] ,
200
+ current_block_count : u16 ,
190
201
blocks_in_last_iteration : u16 ,
191
202
) -> io:: Result < u16 > {
192
- let current_block_count = block_count_sans_ansi_codes ( tokens) ;
193
203
if blocks_in_last_iteration > current_block_count {
194
204
// fill to the end of line to overwrite what was previously there
195
205
writeln ! (
0 commit comments