Need something better than std::ascii::escape_default


#1

I’m looking for a way to pretty-print byte strings in error messages, logs and the like.

The closest thing I could find is ascii::escape_default, but it currently looks like a sore thumb: it does not plug into the infrastructure of Char::escape_default, and the way to process escaped characters is a mutable closure that accepts bytes.

This is the best I could come up with:

fn escape_bytestring(s: &[u8]) -> String {
    let mut acc: Vec<u8> = Vec::with_capacity(s.len());
    for &c in s.iter() {
        ascii::escape_default(c, |e| {
            acc.push(e);
        })
    }
    String::from_utf8(acc).unwrap()
}

#2

ascii::escape_default tries very hard not to allocate, which is why it looks so weird. Wrapping it with your own function seems like the best way to provide allocation-using functionality.


#3

ascii::escape_default tries very hard not to allocate

Returning EscapeDefault (or its byte-wise equivalent) would not seem to be incompatible with this goal: the escape sequences have a small maximum length, so any such sequence could be contained in the iterator struct.

StrExt has allocating escape methods for strings; there could be similar functionality in std::slice::bytes.