Process a single not-ASCII-printable char
per iteration
This avoids having to collect a non-ASCII-printable run before processing it.
This commit is contained in:
parent
aaba972e06
commit
004100c222
@ -2407,8 +2407,8 @@ fn needs_escape(b: u8) -> bool {
|
||||
b > 0x7E || b < 0x20 || b == b'\\' || b == b'"'
|
||||
}
|
||||
|
||||
// the outer loop here splits the string into chunks of printable ASCII, which is just skipped over,
|
||||
// and chunks of other chars (unicode, or ASCII that needs escaping), which is handler per-`char`.
|
||||
// the loop here first skips over runs of printable ASCII as a fast path.
|
||||
// other chars (unicode, or ASCII that needs escaping) are then handled per-`char`.
|
||||
let mut rest = self;
|
||||
while rest.len() > 0 {
|
||||
let Some(non_printable_start) = rest.as_bytes().iter().position(|&b| needs_escape(b))
|
||||
@ -2421,12 +2421,8 @@ fn needs_escape(b: u8) -> bool {
|
||||
// SAFETY: the position was derived from an iterator, so is known to be within bounds, and at a char boundary
|
||||
rest = unsafe { rest.get_unchecked(non_printable_start..) };
|
||||
|
||||
let printable_start =
|
||||
rest.as_bytes().iter().position(|&b| !needs_escape(b)).unwrap_or(rest.len());
|
||||
let prefix;
|
||||
(prefix, rest) = rest.split_at(printable_start);
|
||||
|
||||
for c in prefix.chars() {
|
||||
let mut chars = rest.chars();
|
||||
if let Some(c) = chars.next() {
|
||||
let esc = c.escape_debug_ext(EscapeDebugExtArgs {
|
||||
escape_grapheme_extended: true,
|
||||
escape_single_quote: false,
|
||||
@ -2439,6 +2435,7 @@ fn needs_escape(b: u8) -> bool {
|
||||
}
|
||||
printable_range.end += c.len_utf8();
|
||||
}
|
||||
rest = chars.as_str();
|
||||
}
|
||||
|
||||
f.write_str(&self[printable_range])?;
|
||||
|
Loading…
Reference in New Issue
Block a user