@@ -52,6 +52,7 @@ use margin::Margin;
5252use std:: borrow:: Cow ;
5353use std:: cmp:: { max, min, Ordering , Reverse } ;
5454use std:: collections:: { HashMap , VecDeque } ;
55+ use std:: fmt;
5556use std:: ops:: Range ;
5657use stylesheet:: Stylesheet ;
5758
@@ -198,35 +199,28 @@ impl Renderer {
198199
199200impl Renderer {
200201 pub fn render ( & self , mut message : Message < ' _ > ) -> String {
201- let mut buffer = StyledBuffer :: new ( ) ;
202202 let max_line_num_len = if self . anonymized_line_numbers {
203203 ANONYMIZED_LINE_NUM . len ( )
204204 } else {
205205 let n = message. max_line_number ( ) ;
206206 num_decimal_digits ( n)
207207 } ;
208208 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- } ;
214209 if let Some ( first) = message. groups . first_mut ( ) {
215210 first. elements . insert ( 0 , title) ;
216211 } else {
217212 message. groups . push ( Group :: new ( ) . element ( title) ) ;
218213 }
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 ( )
222215 }
223216
224217 fn render_message (
225218 & self ,
226- buffer : & mut StyledBuffer ,
227219 message : Message < ' _ > ,
228220 max_line_num_len : usize ,
229- ) {
221+ ) -> Result < String , fmt:: Error > {
222+ let mut out_string = String :: new ( ) ;
223+
230224 let og_primary_origin = message
231225 . groups
232226 . iter ( )
@@ -264,6 +258,7 @@ impl Renderer {
264258 ) ;
265259 let group_len = message. groups . len ( ) ;
266260 for ( g, group) in message. groups . into_iter ( ) . enumerate ( ) {
261+ let mut buffer = StyledBuffer :: new ( ) ;
267262 let primary_origin = group
268263 . elements
269264 . iter ( )
@@ -295,6 +290,14 @@ impl Renderer {
295290 } )
296291 . unwrap_or_default ( ) ,
297292 ) ;
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 ) ;
298301 let mut source_map_annotated_lines = VecDeque :: new ( ) ;
299302 let mut max_depth = 0 ;
300303 for e in & group. elements {
@@ -313,7 +316,7 @@ impl Renderer {
313316 match & section {
314317 Element :: Title ( title) => {
315318 self . render_title (
316- buffer,
319+ & mut buffer,
317320 title,
318321 peek,
319322 max_line_num_len,
@@ -334,7 +337,7 @@ impl Renderer {
334337 source_map_annotated_lines. pop_front ( )
335338 {
336339 self . render_snippet_annotations (
337- buffer,
340+ & mut buffer,
338341 max_line_num_len,
339342 cause,
340343 primary_origin,
@@ -345,19 +348,20 @@ impl Renderer {
345348 ) ;
346349
347350 if g == 0 && group_len > 1 {
351+ let current_line = buffer. num_lines ( ) ;
348352 if matches ! ( peek, Some ( Element :: Title ( level) ) if level. level. name != Some ( None ) )
349353 {
350354 self . draw_col_separator_no_space (
351- buffer,
352- buffer . num_lines ( ) ,
355+ & mut buffer,
356+ current_line ,
353357 max_line_num_len + 1 ,
354358 ) ;
355359 // We want to draw the separator when it is
356360 // requested, or when it is the last element
357361 } else if peek. is_none ( ) {
358362 self . draw_col_separator_end (
359- buffer,
360- buffer . num_lines ( ) ,
363+ & mut buffer,
364+ current_line ,
361365 max_line_num_len + 1 ,
362366 ) ;
363367 }
@@ -369,7 +373,7 @@ impl Renderer {
369373 Element :: Suggestion ( suggestion) => {
370374 let source_map = SourceMap :: new ( suggestion. source , suggestion. line_start ) ;
371375 self . emit_suggestion_default (
372- buffer,
376+ & mut buffer,
373377 suggestion,
374378 max_line_num_len,
375379 & source_map,
@@ -380,13 +384,14 @@ impl Renderer {
380384 }
381385
382386 Element :: Origin ( origin) => {
383- self . render_origin ( buffer, max_line_num_len, origin) ;
387+ self . render_origin ( & mut buffer, max_line_num_len, origin) ;
384388 last_was_suggestion = false ;
385389 }
386390 Element :: Padding ( _) => {
391+ let current_line = buffer. num_lines ( ) ;
387392 self . draw_col_separator_no_space (
388- buffer,
389- buffer . num_lines ( ) ,
393+ & mut buffer,
394+ current_line ,
390395 max_line_num_len + 1 ,
391396 ) ;
392397 }
@@ -396,23 +401,31 @@ impl Renderer {
396401 || ( matches ! ( section, Element :: Title ( _) ) && i == 0 )
397402 || matches ! ( section, Element :: Title ( level) if level. level. name == Some ( None ) ) )
398403 {
404+ let current_line = buffer. num_lines ( ) ;
399405 if peek. is_none ( ) && group_len > 1 {
400406 self . draw_col_separator_end (
401- buffer,
402- buffer . num_lines ( ) ,
407+ & mut buffer,
408+ current_line ,
403409 max_line_num_len + 1 ,
404410 ) ;
405411 } else if matches ! ( peek, Some ( Element :: Title ( level) ) if level. level. name != Some ( None ) )
406412 {
407413 self . draw_col_separator_no_space (
408- buffer,
409- buffer . num_lines ( ) ,
414+ & mut buffer,
415+ current_line ,
410416 max_line_num_len + 1 ,
411417 ) ;
412418 }
413419 }
414420 }
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+ }
415427 }
428+ Ok ( out_string)
416429 }
417430
418431 #[ allow( clippy:: too_many_arguments) ]
0 commit comments