@@ -411,47 +411,70 @@ pub fn write_summary_table(
411411 . unwrap_or_else ( || "N/A" . to_string ( ) )
412412 }
413413
414- writeln ! (
415- result,
416- r#"| | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
417- |:---:|:---:|:---:|:---:|:---:|:---:|"#
418- )
419- . unwrap ( ) ;
420- writeln ! (
421- result,
422- "| count{} | {} | {} | {} | {} | {} |" ,
423- if with_footnotes { "[^1]" } else { "" } ,
424- primary. num_regressions,
425- secondary. num_regressions,
426- primary. num_improvements,
427- secondary. num_improvements,
428- primary. num_regressions + primary. num_improvements
429- )
430- . unwrap ( ) ;
431-
432- writeln ! (
433- result,
434- "| mean{} | {} | {} | {} | {} | {} |" ,
435- if with_footnotes { "[^2]" } else { "" } ,
436- render_stat( primary. num_regressions, || Some (
437- primary. arithmetic_mean_of_regressions( )
438- ) ) ,
439- render_stat( secondary. num_regressions, || Some (
440- secondary. arithmetic_mean_of_regressions( )
441- ) ) ,
442- render_stat( primary. num_improvements, || Some (
443- primary. arithmetic_mean_of_improvements( )
444- ) ) ,
445- render_stat( secondary. num_improvements, || Some (
446- secondary. arithmetic_mean_of_improvements( )
447- ) ) ,
414+ let columns = [
415+ " " , // we want at least 10 spaces to accommodate "count[^1]"
416+ "Regressions πΏ <br />(primary)" ,
417+ "Regressions πΏ <br />(secondary)" ,
418+ "Improvements π <br />(primary)" ,
419+ "Improvements π <br />(secondary)" ,
420+ "All πΏ π <br />(primary)" ,
421+ ] ;
422+ let counts: Vec < usize > = columns
423+ . iter ( )
424+ . map ( |s| {
425+ // Unicode emojis usually have width equal to ~2 chars (maybe? :) ).
426+ let count = s. chars ( ) . count ( ) ;
427+ if s. chars ( ) . any ( |c| !c. is_whitespace ( ) ) {
428+ count + 1
429+ } else {
430+ count
431+ }
432+ } )
433+ . collect ( ) ;
434+ for column in & columns {
435+ write ! ( result, "| {} " , column) . unwrap ( ) ;
436+ }
437+ result. push_str ( "|\n " ) ;
438+ for & count in & counts {
439+ write ! ( result, "|:{}:" , "-" . repeat( count) ) . unwrap ( ) ;
440+ }
441+ result. push_str ( "|\n " ) ;
442+
443+ let mut render_row = |row : Vec < String > | {
444+ debug_assert_eq ! ( row. len( ) , columns. len( ) ) ;
445+ for ( column, & count) in row. into_iter ( ) . zip ( & counts) {
446+ write ! ( result, "| {:<1$} " , column, count) . unwrap ( ) ;
447+ }
448+ result. push_str ( "|\n " ) ;
449+ } ;
450+ render_row ( vec ! [
451+ format!( "count{}" , if with_footnotes { "[^1]" } else { "" } ) ,
452+ primary. num_regressions. to_string( ) ,
453+ secondary. num_regressions. to_string( ) ,
454+ primary. num_improvements. to_string( ) ,
455+ secondary. num_improvements. to_string( ) ,
456+ ( primary. num_regressions + primary. num_improvements) . to_string( ) ,
457+ ] ) ;
458+ render_row ( vec ! [
459+ format!( "mean{}" , if with_footnotes { "[^2]" } else { "" } ) ,
460+ render_stat( primary. num_regressions, || {
461+ Some ( primary. arithmetic_mean_of_regressions( ) )
462+ } ) ,
463+ render_stat( secondary. num_regressions, || {
464+ Some ( secondary. arithmetic_mean_of_regressions( ) )
465+ } ) ,
466+ render_stat( primary. num_improvements, || {
467+ Some ( primary. arithmetic_mean_of_improvements( ) )
468+ } ) ,
469+ render_stat( secondary. num_improvements, || {
470+ Some ( secondary. arithmetic_mean_of_improvements( ) )
471+ } ) ,
448472 if primary. is_empty( ) {
449473 "N/A" . to_string( )
450474 } else {
451475 format!( "{:.1}%" , primary. arithmetic_mean_of_changes( ) )
452- }
453- )
454- . unwrap ( ) ;
476+ } ,
477+ ] ) ;
455478
456479 let largest_change = if primary. is_empty ( ) {
457480 "N/A" . to_string ( )
@@ -478,24 +501,30 @@ pub fn write_summary_table(
478501 format ! ( "{:.1}%" , change * 100.0 )
479502 } ;
480503
481- writeln ! (
482- result,
483- "| max | {} | {} | {} | {} | {} |" ,
484- render_stat( primary. num_regressions, || primary
485- . largest_regression( )
486- . map( |r| r. relative_change( ) * 100.0 ) ) ,
487- render_stat( secondary. num_regressions, || secondary
488- . largest_regression( )
489- . map( |r| r. relative_change( ) * 100.0 ) ) ,
490- render_stat( primary. num_improvements, || primary
491- . largest_improvement( )
492- . map( |r| r. relative_change( ) * 100.0 ) ) ,
493- render_stat( secondary. num_improvements, || secondary
494- . largest_improvement( )
495- . map( |r| r. relative_change( ) * 100.0 ) ) ,
496- largest_change
497- )
498- . unwrap ( ) ;
504+ render_row ( vec ! [
505+ "max" . to_string( ) ,
506+ render_stat( primary. num_regressions, || {
507+ primary
508+ . largest_regression( )
509+ . map( |r| r. relative_change( ) * 100.0 )
510+ } ) ,
511+ render_stat( secondary. num_regressions, || {
512+ secondary
513+ . largest_regression( )
514+ . map( |r| r. relative_change( ) * 100.0 )
515+ } ) ,
516+ render_stat( primary. num_improvements, || {
517+ primary
518+ . largest_improvement( )
519+ . map( |r| r. relative_change( ) * 100.0 )
520+ } ) ,
521+ render_stat( secondary. num_improvements, || {
522+ secondary
523+ . largest_improvement( )
524+ . map( |r| r. relative_change( ) * 100.0 )
525+ } ) ,
526+ largest_change,
527+ ] ) ;
499528
500529 if with_footnotes {
501530 writeln ! (
@@ -1222,11 +1251,11 @@ mod tests {
12221251 ( Category :: Primary , 1.0 , 3.0 ) ,
12231252 ] ,
12241253 r#"
1225- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1226- |:---:|:---:|:---:|:---:|:---:|:---:|
1227- | count[^1] | 3 | 0 | 0 | 0 | 3 |
1228- | mean[^2] | 146.7% | N/A | N/A | N/A | 146.7% |
1229- | max | 200.0% | N/A | N/A | N/A | 200.0% |
1254+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1255+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1256+ | count[^1] | 3 | 0 | 0 | 0 | 3 |
1257+ | mean[^2] | 146.7% | N/A | N/A | N/A | 146.7% |
1258+ | max | 200.0% | N/A | N/A | N/A | 200.0% |
12301259
12311260[^1]: *number of relevant changes*
12321261[^2]: *the arithmetic mean of the percent change*
@@ -1244,11 +1273,11 @@ mod tests {
12441273 ( Category :: Primary , 4.0 , 1.0 ) ,
12451274 ] ,
12461275 r#"
1247- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1248- |:---:|:---:|:---:|:---:|:---:|:---:|
1249- | count[^1] | 0 | 0 | 3 | 0 | 3 |
1250- | mean[^2] | N/A | N/A | -71.7% | N/A | -71.7% |
1251- | max | N/A | N/A | -80.0% | N/A | -80.0% |
1276+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1277+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1278+ | count[^1] | 0 | 0 | 3 | 0 | 3 |
1279+ | mean[^2] | N/A | N/A | -71.7% | N/A | -71.7% |
1280+ | max | N/A | N/A | -80.0% | N/A | -80.0% |
12521281
12531282[^1]: *number of relevant changes*
12541283[^2]: *the arithmetic mean of the percent change*
@@ -1266,11 +1295,11 @@ mod tests {
12661295 ( Category :: Secondary , 4.0 , 1.0 ) ,
12671296 ] ,
12681297 r#"
1269- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1270- |:---:|:---:|:---:|:---:|:---:|:---:|
1271- | count[^1] | 0 | 0 | 0 | 3 | 0 |
1272- | mean[^2] | N/A | N/A | N/A | -71.7% | N/A |
1273- | max | N/A | N/A | N/A | -80.0% | N/A |
1298+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1299+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1300+ | count[^1] | 0 | 0 | 0 | 3 | 0 |
1301+ | mean[^2] | N/A | N/A | N/A | -71.7% | N/A |
1302+ | max | N/A | N/A | N/A | -80.0% | N/A |
12741303
12751304[^1]: *number of relevant changes*
12761305[^2]: *the arithmetic mean of the percent change*
@@ -1288,11 +1317,11 @@ mod tests {
12881317 ( Category :: Secondary , 1.0 , 3.0 ) ,
12891318 ] ,
12901319 r#"
1291- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1292- |:---:|:---:|:---:|:---:|:---:|:---:|
1293- | count[^1] | 0 | 3 | 0 | 0 | 0 |
1294- | mean[^2] | N/A | 146.7% | N/A | N/A | N/A |
1295- | max | N/A | 200.0% | N/A | N/A | N/A |
1320+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1321+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1322+ | count[^1] | 0 | 3 | 0 | 0 | 0 |
1323+ | mean[^2] | N/A | 146.7% | N/A | N/A | N/A |
1324+ | max | N/A | 200.0% | N/A | N/A | N/A |
12961325
12971326[^1]: *number of relevant changes*
12981327[^2]: *the arithmetic mean of the percent change*
@@ -1311,11 +1340,11 @@ mod tests {
13111340 ( Category :: Primary , 4.0 , 1.0 ) ,
13121341 ] ,
13131342 r#"
1314- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1315- |:---:|:---:|:---:|:---:|:---:|:---:|
1316- | count[^1] | 2 | 0 | 2 | 0 | 4 |
1317- | mean[^2] | 150.0% | N/A | -62.5% | N/A | 43.8% |
1318- | max | 200.0% | N/A | -75.0% | N/A | 200.0% |
1343+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1344+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1345+ | count[^1] | 2 | 0 | 2 | 0 | 4 |
1346+ | mean[^2] | 150.0% | N/A | -62.5% | N/A | 43.8% |
1347+ | max | 200.0% | N/A | -75.0% | N/A | 200.0% |
13191348
13201349[^1]: *number of relevant changes*
13211350[^2]: *the arithmetic mean of the percent change*
@@ -1336,11 +1365,11 @@ mod tests {
13361365 ( Category :: Primary , 4.0 , 1.0 ) ,
13371366 ] ,
13381367 r#"
1339- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1340- |:---:|:---:|:---:|:---:|:---:|:---:|
1341- | count[^1] | 2 | 1 | 2 | 1 | 4 |
1342- | mean[^2] | 150.0% | 100.0% | -62.5% | -66.7% | 43.8% |
1343- | max | 200.0% | 100.0% | -75.0% | -66.7% | 200.0% |
1368+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1369+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1370+ | count[^1] | 2 | 1 | 2 | 1 | 4 |
1371+ | mean[^2] | 150.0% | 100.0% | -62.5% | -66.7% | 43.8% |
1372+ | max | 200.0% | 100.0% | -75.0% | -66.7% | 200.0% |
13441373
13451374[^1]: *number of relevant changes*
13461375[^2]: *the arithmetic mean of the percent change*
@@ -1357,11 +1386,11 @@ mod tests {
13571386 ( Category :: Primary , 5.0 , 6.0 ) ,
13581387 ] ,
13591388 r#"
1360- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1361- |:---:|:---:|:---:|:---:|:---:|:---:|
1362- | count[^1] | 1 | 0 | 1 | 0 | 2 |
1363- | mean[^2] | 20.0% | N/A | -50.0% | N/A | -15.0% |
1364- | max | 20.0% | N/A | -50.0% | N/A | -50.0% |
1389+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1390+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1391+ | count[^1] | 1 | 0 | 1 | 0 | 2 |
1392+ | mean[^2] | 20.0% | N/A | -50.0% | N/A | -15.0% |
1393+ | max | 20.0% | N/A | -50.0% | N/A | -50.0% |
13651394
13661395[^1]: *number of relevant changes*
13671396[^2]: *the arithmetic mean of the percent change*
@@ -1378,11 +1407,11 @@ mod tests {
13781407 ( Category :: Primary , 6.0 , 5.0 ) ,
13791408 ] ,
13801409 r#"
1381- | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1382- |:---:|:---:|:---:|:---:|:---:|:---:|
1383- | count[^1] | 1 | 0 | 1 | 0 | 2 |
1384- | mean[^2] | 100.0% | N/A | -16.7% | N/A | 41.7% |
1385- | max | 100.0% | N/A | -16.7% | N/A | 100.0% |
1410+ | | Regressions πΏ <br />(primary) | Regressions πΏ <br />(secondary) | Improvements π <br />(primary) | Improvements π <br />(secondary) | All πΏ π <br />(primary) |
1411+ |:---------- :|:------------------------------ :|:-------------------------------- :|:------------------------------- :|:--------------------------------- :|:--------------------- ---:|
1412+ | count[^1] | 1 | 0 | 1 | 0 | 2 |
1413+ | mean[^2] | 100.0% | N/A | -16.7% | N/A | 41.7% |
1414+ | max | 100.0% | N/A | -16.7% | N/A | 100.0% |
13861415
13871416[^1]: *number of relevant changes*
13881417[^2]: *the arithmetic mean of the percent change*
0 commit comments