BurntSushi / BurntSushi/bstr

Write escaped string into a buffer

Open
#34 4 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Rust
Stars
1.1k
Forks
77
PR merge metrics
No merged PRs in 30d

Description

Hi @BurntSushi,

I'm using `bstr` for turning a `Vec`-like structure into debug strings and error messages. Specifically, I'm working on a Ruby implementation. In Ruby `String` is a `Vec` with a default UTF-8 encoding with no guarantees that the bytes are actually valid UTF-8.

`bstr` is the means by which I interpret these byte vectors as UTF-8 the best I can.

The `fmt::Debug` implementation on `&BStr` is very close to what I'd like, but I cannot use it because it wraps the escaped string in quotes. I need control of the output since these strings are being but into error messages.

I've put together this function for writing the escaped representation to an arbitrary `fmt::Write` (cribbing heavily form the `fmt::Debug` impl on `&BStr`).

```rust
pub fn escape_unicode(mut f: T, string: &[u8]) -> Result<(), WriteError>
where
T: fmt::Write,
{
let buf = bstr::B(string);
for (start, end, ch) in buf.char_indices() {
if ch == '\u{FFFD}' {
for byte in buf[start..end].as_bytes() {
write!(f, r"\x{:X}", byte)?;
}
} else {
write!(f, "{}", ch.escape_debug())?;
}
}
Ok(())
}
```

Here's an example usage:

```rust
let mut message = String::from("undefined group name reference: \"");
string::escape_unicode(&mut message, name)?;
message.push('"');
Err(Exception::from(IndexError::new(interp, message)))
```

I'm trying to generate a message like this:

```console
$ ruby -e 'm = /(.)/.match("a"); m["abc-\xFF"]'
Traceback (most recent call last):
1: from -e:1:in `'
-e:1:in `[]': undefined group name reference: "abc-\xFF" (IndexError)
```

Is this patch something you would consider upstreaming?

Contributor guide

No contributing guide indexed for this repository

Research direction

Review the existing fmt::Debug implementation on &BStr and the proposed escape_unicode function, which writes escaped bytes to an arbitrary fmt::Write. Check how formatting helpers are exposed in the library, then confirm the expected behavior for invalid UTF-8 and escaped characters before deciding whether to add this API.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.