Description
The behaviors of char::escape_debug
, str::escape_debug
, and <str as Debug>::fmt
are confusingly inconsistent with each other, and the inconsistencies are poorly documented.
fn main() {
let wat = "a\u{301}'";
println!("{:?}", wat);
println!("\"{}\"", wat.escape_debug());
println!(
"\"{}\"",
wat.chars()
.flat_map(|ch| ch.escape_debug())
.collect::<String>()
);
}
"a\u{301}'"
"á\'"
"a\u{301}\'"
It seems defensible that char::escape_debug
escapes single-quotes while <str as Debug>::fmt
doesn't, since char_escape_debug
doesn't know whether it's being used to escape a character literal or a string literal. But if a difference is going to exist, it's less defensible that str::escape_debug
should follow the behavior of char::escape_debug
rather than the behavior of <str as Debug>::fmt
.
str::escape_debug
and <str as Debug>::fmt
's differing behavior on grapheme extenders makes no sense at all. Furthermore, if the escaping of grapheme extenders is going to be position-dependent (a bad idea IMO), then the rule should be that they are unescaped only if they are preceded by an unescaped character. The current rule gives absurd results in cases like
fn main() {
println!("{}", "\u{301}\u{301}".escape_debug());
}
\u{301}́