@@ -2402,23 +2402,47 @@ impl Display for bool {
2402
2402
impl Debug for str {
2403
2403
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result {
2404
2404
f. write_char ( '"' ) ?;
2405
- let mut from = 0 ;
2406
- for ( i, c) in self . char_indices ( ) {
2407
- let esc = c. escape_debug_ext ( EscapeDebugExtArgs {
2408
- escape_grapheme_extended : true ,
2409
- escape_single_quote : false ,
2410
- escape_double_quote : true ,
2411
- } ) ;
2412
- // If char needs escaping, flush backlog so far and write, else skip
2413
- if esc. len ( ) != 1 {
2414
- f. write_str ( & self [ from..i] ) ?;
2415
- for c in esc {
2416
- f. write_char ( c) ?;
2405
+
2406
+ // substring we know is printable
2407
+ let mut printable_range = 0 ..0 ;
2408
+
2409
+ fn needs_escape ( b : u8 ) -> bool {
2410
+ b > 0x7E || b < 0x20 || b == b'\\' || b == b'"'
2411
+ }
2412
+
2413
+ // the loop here first skips over runs of printable ASCII as a fast path.
2414
+ // other chars (unicode, or ASCII that needs escaping) are then handled per-`char`.
2415
+ let mut rest = self ;
2416
+ while rest. len ( ) > 0 {
2417
+ let Some ( non_printable_start) = rest. as_bytes ( ) . iter ( ) . position ( |& b| needs_escape ( b) )
2418
+ else {
2419
+ printable_range. end += rest. len ( ) ;
2420
+ break ;
2421
+ } ;
2422
+
2423
+ printable_range. end += non_printable_start;
2424
+ // SAFETY: the position was derived from an iterator, so is known to be within bounds, and at a char boundary
2425
+ rest = unsafe { rest. get_unchecked ( non_printable_start..) } ;
2426
+
2427
+ let mut chars = rest. chars ( ) ;
2428
+ if let Some ( c) = chars. next ( ) {
2429
+ let esc = c. escape_debug_ext ( EscapeDebugExtArgs {
2430
+ escape_grapheme_extended : true ,
2431
+ escape_single_quote : false ,
2432
+ escape_double_quote : true ,
2433
+ } ) ;
2434
+ if esc. len ( ) != 1 {
2435
+ f. write_str ( & self [ printable_range. clone ( ) ] ) ?;
2436
+ Display :: fmt ( & esc, f) ?;
2437
+ printable_range. start = printable_range. end + c. len_utf8 ( ) ;
2417
2438
}
2418
- from = i + c. len_utf8 ( ) ;
2439
+ printable_range . end += c. len_utf8 ( ) ;
2419
2440
}
2441
+ rest = chars. as_str ( ) ;
2420
2442
}
2421
- f. write_str ( & self [ from..] ) ?;
2443
+
2444
+ f. write_str ( & self [ printable_range] ) ?;
2445
+
2422
2446
f. write_char ( '"' )
2423
2447
}
2424
2448
}
@@ -2434,13 +2458,12 @@ impl Display for str {
2434
2458
impl Debug for char {
2435
2459
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> Result {
2436
2460
f. write_char ( '\'' ) ?;
2437
- for c in self . escape_debug_ext ( EscapeDebugExtArgs {
2461
+ let esc = self . escape_debug_ext ( EscapeDebugExtArgs {
2438
2462
escape_grapheme_extended : true ,
2439
2463
escape_single_quote : true ,
2440
2464
escape_double_quote : false ,
2441
- } ) {
2442
- f. write_char ( c) ?
2443
- }
2465
+ } ) ;
2466
+ Display :: fmt ( & esc, f) ?;
2444
2467
f. write_char ( '\'' )
2445
2468
}
2446
2469
}
0 commit comments