@@ -261,10 +261,6 @@ impl<T: Write> JsonFormatter<T> {
261
261
}
262
262
}
263
263
264
- fn naive_json_escape ( input : & str ) -> String {
265
- input. replace ( "\\ " , "\\ \\ " ) . replace ( "\" " , "\\ \" " )
266
- }
267
-
268
264
impl < T : Write > OutputFormatter for JsonFormatter < T > {
269
265
fn write_run_start ( & mut self , len : usize ) -> io:: Result < ( ) > {
270
266
self . write_str (
@@ -294,7 +290,7 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
294
290
TrFailedMsg ( ref m) => {
295
291
format ! ( r#"{{ "type": "test", "event": "failed", "name": "{}", "message": "{}" }}"# ,
296
292
desc. name,
297
- naive_json_escape ( m) )
293
+ EscapedString ( m) )
298
294
} ,
299
295
300
296
TrIgnored => {
@@ -307,16 +303,22 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
307
303
desc. name)
308
304
} ,
309
305
310
- TrMetrics ( ref mm) => {
311
- format ! ( r#"{{ "type": "metrics", "name": "{}", "metrics": "{}" }}"# ,
312
- desc. name,
313
- mm. fmt_metrics( ) )
314
- } ,
315
-
316
306
TrBench ( ref bs) => {
317
- format ! ( r#"{{ "type": "bench", "name": "{}", "bench": "{}" }}"# ,
307
+ let median = bs. ns_iter_summ . median as usize ;
308
+ let deviation = ( bs. ns_iter_summ . max - bs. ns_iter_summ . min ) as usize ;
309
+
310
+ let mbps = if bs. mb_s == 0 {
311
+ "" . into ( )
312
+ }
313
+ else {
314
+ format ! ( r#", "mib_per_second": {}"# , bs. mb_s)
315
+ } ;
316
+
317
+ format ! ( r#"{{ "type": "bench", "name": "{}", "median": {}, "deviation": {}{} }}"# ,
318
318
desc. name,
319
- fmt_bench_samples( bs) )
319
+ median,
320
+ deviation,
321
+ mbps)
320
322
} ,
321
323
} ;
322
324
@@ -330,7 +332,7 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
330
332
331
333
fn write_run_finish ( & mut self , state : & ConsoleTestState ) -> io:: Result < bool > {
332
334
333
- self . write_str ( & * format ! ( "{{ \" type\" : \" suite\" ,\
335
+ self . write_str ( & * format ! ( "{{ \" type\" : \" suite\" , \
334
336
\" event\" : \" {}\" , \
335
337
\" passed\" : {}, \
336
338
\" failed\" : {}, \
@@ -348,15 +350,78 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
348
350
349
351
for & ( ref f, ref stdout) in & state. failures {
350
352
if !stdout. is_empty ( ) {
351
- let output = naive_json_escape ( & * String :: from_utf8_lossy ( stdout) ) ;
352
-
353
353
self . write_str (
354
354
& * format ! ( r#"{{ "type": "test_output", "name": "{}", "output": "{}" }}"# ,
355
355
f. name,
356
- output ) ) ?;
356
+ EscapedString ( & * String :: from_utf8_lossy ( stdout ) ) ) ) ?;
357
357
}
358
358
}
359
359
360
360
Ok ( state. failed == 0 )
361
361
}
362
362
}
363
+
364
+ /// A formatting utility used to print strings with characters in need of escaping.
365
+ /// Base code taken form `libserialize::json::escape_str`
366
+ struct EscapedString < ' a > ( & ' a str ) ;
367
+
368
+ impl < ' a > :: std:: fmt:: Display for EscapedString < ' a > {
369
+ fn fmt ( & self , f : & mut :: std:: fmt:: Formatter ) -> :: std:: fmt:: Result {
370
+ let mut start = 0 ;
371
+
372
+ for ( i, byte) in self . 0 . bytes ( ) . enumerate ( ) {
373
+ let escaped = match byte {
374
+ b'"' => "\\ \" " ,
375
+ b'\\' => "\\ \\ " ,
376
+ b'\x00' => "\\ u0000" ,
377
+ b'\x01' => "\\ u0001" ,
378
+ b'\x02' => "\\ u0002" ,
379
+ b'\x03' => "\\ u0003" ,
380
+ b'\x04' => "\\ u0004" ,
381
+ b'\x05' => "\\ u0005" ,
382
+ b'\x06' => "\\ u0006" ,
383
+ b'\x07' => "\\ u0007" ,
384
+ b'\x08' => "\\ b" ,
385
+ b'\t' => "\\ t" ,
386
+ b'\n' => "\\ n" ,
387
+ b'\x0b' => "\\ u000b" ,
388
+ b'\x0c' => "\\ f" ,
389
+ b'\r' => "\\ r" ,
390
+ b'\x0e' => "\\ u000e" ,
391
+ b'\x0f' => "\\ u000f" ,
392
+ b'\x10' => "\\ u0010" ,
393
+ b'\x11' => "\\ u0011" ,
394
+ b'\x12' => "\\ u0012" ,
395
+ b'\x13' => "\\ u0013" ,
396
+ b'\x14' => "\\ u0014" ,
397
+ b'\x15' => "\\ u0015" ,
398
+ b'\x16' => "\\ u0016" ,
399
+ b'\x17' => "\\ u0017" ,
400
+ b'\x18' => "\\ u0018" ,
401
+ b'\x19' => "\\ u0019" ,
402
+ b'\x1a' => "\\ u001a" ,
403
+ b'\x1b' => "\\ u001b" ,
404
+ b'\x1c' => "\\ u001c" ,
405
+ b'\x1d' => "\\ u001d" ,
406
+ b'\x1e' => "\\ u001e" ,
407
+ b'\x1f' => "\\ u001f" ,
408
+ b'\x7f' => "\\ u007f" ,
409
+ _ => { continue ; }
410
+ } ;
411
+
412
+ if start < i {
413
+ f. write_str ( & self . 0 [ start..i] ) ?;
414
+ }
415
+
416
+ f. write_str ( escaped) ?;
417
+
418
+ start = i + 1 ;
419
+ }
420
+
421
+ if start != self . 0 . len ( ) {
422
+ f. write_str ( & self . 0 [ start..] ) ?;
423
+ }
424
+
425
+ Ok ( ( ) )
426
+ }
427
+ }
0 commit comments