@@ -52,6 +52,7 @@ use margin::Margin;
52
52
use std:: borrow:: Cow ;
53
53
use std:: cmp:: { max, min, Ordering , Reverse } ;
54
54
use std:: collections:: { HashMap , VecDeque } ;
55
+ use std:: fmt;
55
56
use std:: ops:: Range ;
56
57
use stylesheet:: Stylesheet ;
57
58
@@ -198,35 +199,28 @@ impl Renderer {
198
199
199
200
impl Renderer {
200
201
pub fn render ( & self , mut message : Message < ' _ > ) -> String {
201
- let mut buffer = StyledBuffer :: new ( ) ;
202
202
let max_line_num_len = if self . anonymized_line_numbers {
203
203
ANONYMIZED_LINE_NUM . len ( )
204
204
} else {
205
205
let n = message. max_line_number ( ) ;
206
206
num_decimal_digits ( n)
207
207
} ;
208
208
let title = message. groups . remove ( 0 ) . elements . remove ( 0 ) ;
209
- let level = if let Element :: Title ( title) = & title {
210
- title. level . clone ( )
211
- } else {
212
- panic ! ( "Expected a title as the first element of the message" )
213
- } ;
214
209
if let Some ( first) = message. groups . first_mut ( ) {
215
210
first. elements . insert ( 0 , title) ;
216
211
} else {
217
212
message. groups . push ( Group :: new ( ) . element ( title) ) ;
218
213
}
219
- self . render_message ( & mut buffer, message, max_line_num_len) ;
220
-
221
- buffer. render ( level, & self . stylesheet ) . unwrap ( )
214
+ self . render_message ( message, max_line_num_len) . unwrap ( )
222
215
}
223
216
224
217
fn render_message (
225
218
& self ,
226
- buffer : & mut StyledBuffer ,
227
219
message : Message < ' _ > ,
228
220
max_line_num_len : usize ,
229
- ) {
221
+ ) -> Result < String , fmt:: Error > {
222
+ let mut out_string = String :: new ( ) ;
223
+
230
224
let og_primary_origin = message
231
225
. groups
232
226
. iter ( )
@@ -264,6 +258,7 @@ impl Renderer {
264
258
) ;
265
259
let group_len = message. groups . len ( ) ;
266
260
for ( g, group) in message. groups . into_iter ( ) . enumerate ( ) {
261
+ let mut buffer = StyledBuffer :: new ( ) ;
267
262
let primary_origin = group
268
263
. elements
269
264
. iter ( )
@@ -295,6 +290,14 @@ impl Renderer {
295
290
} )
296
291
. unwrap_or_default ( ) ,
297
292
) ;
293
+ let level = group
294
+ . elements
295
+ . iter ( )
296
+ . find_map ( |s| match & s {
297
+ Element :: Title ( title) => Some ( title. level . clone ( ) ) ,
298
+ _ => None ,
299
+ } )
300
+ . unwrap_or ( Level :: ERROR ) ;
298
301
let mut source_map_annotated_lines = VecDeque :: new ( ) ;
299
302
let mut max_depth = 0 ;
300
303
for e in & group. elements {
@@ -313,7 +316,7 @@ impl Renderer {
313
316
match & section {
314
317
Element :: Title ( title) => {
315
318
self . render_title (
316
- buffer,
319
+ & mut buffer,
317
320
title,
318
321
peek,
319
322
max_line_num_len,
@@ -334,7 +337,7 @@ impl Renderer {
334
337
source_map_annotated_lines. pop_front ( )
335
338
{
336
339
self . render_snippet_annotations (
337
- buffer,
340
+ & mut buffer,
338
341
max_line_num_len,
339
342
cause,
340
343
primary_origin,
@@ -345,19 +348,20 @@ impl Renderer {
345
348
) ;
346
349
347
350
if g == 0 && group_len > 1 {
351
+ let current_line = buffer. num_lines ( ) ;
348
352
if matches ! ( peek, Some ( Element :: Title ( level) ) if level. level. name != Some ( None ) )
349
353
{
350
354
self . draw_col_separator_no_space (
351
- buffer,
352
- buffer . num_lines ( ) ,
355
+ & mut buffer,
356
+ current_line ,
353
357
max_line_num_len + 1 ,
354
358
) ;
355
359
// We want to draw the separator when it is
356
360
// requested, or when it is the last element
357
361
} else if peek. is_none ( ) {
358
362
self . draw_col_separator_end (
359
- buffer,
360
- buffer . num_lines ( ) ,
363
+ & mut buffer,
364
+ current_line ,
361
365
max_line_num_len + 1 ,
362
366
) ;
363
367
}
@@ -369,7 +373,7 @@ impl Renderer {
369
373
Element :: Suggestion ( suggestion) => {
370
374
let source_map = SourceMap :: new ( suggestion. source , suggestion. line_start ) ;
371
375
self . emit_suggestion_default (
372
- buffer,
376
+ & mut buffer,
373
377
suggestion,
374
378
max_line_num_len,
375
379
& source_map,
@@ -380,13 +384,14 @@ impl Renderer {
380
384
}
381
385
382
386
Element :: Origin ( origin) => {
383
- self . render_origin ( buffer, max_line_num_len, origin) ;
387
+ self . render_origin ( & mut buffer, max_line_num_len, origin) ;
384
388
last_was_suggestion = false ;
385
389
}
386
390
Element :: Padding ( _) => {
391
+ let current_line = buffer. num_lines ( ) ;
387
392
self . draw_col_separator_no_space (
388
- buffer,
389
- buffer . num_lines ( ) ,
393
+ & mut buffer,
394
+ current_line ,
390
395
max_line_num_len + 1 ,
391
396
) ;
392
397
}
@@ -396,23 +401,31 @@ impl Renderer {
396
401
|| ( matches ! ( section, Element :: Title ( _) ) && i == 0 )
397
402
|| matches ! ( section, Element :: Title ( level) if level. level. name == Some ( None ) ) )
398
403
{
404
+ let current_line = buffer. num_lines ( ) ;
399
405
if peek. is_none ( ) && group_len > 1 {
400
406
self . draw_col_separator_end (
401
- buffer,
402
- buffer . num_lines ( ) ,
407
+ & mut buffer,
408
+ current_line ,
403
409
max_line_num_len + 1 ,
404
410
) ;
405
411
} else if matches ! ( peek, Some ( Element :: Title ( level) ) if level. level. name != Some ( None ) )
406
412
{
407
413
self . draw_col_separator_no_space (
408
- buffer,
409
- buffer . num_lines ( ) ,
414
+ & mut buffer,
415
+ current_line ,
410
416
max_line_num_len + 1 ,
411
417
) ;
412
418
}
413
419
}
414
420
}
421
+ buffer. render ( level, & self . stylesheet , & mut out_string) ?;
422
+ if g != group_len - 1 {
423
+ use std:: fmt:: Write ;
424
+
425
+ writeln ! ( out_string) ?;
426
+ }
415
427
}
428
+ Ok ( out_string)
416
429
}
417
430
418
431
#[ allow( clippy:: too_many_arguments) ]
0 commit comments