use std::borrow::Cow;
pub(crate) fn escape_text(text: &str) -> Cow<'_, str> {
let mut safe = None;
for (idx, ch) in text.char_indices() {
if ch.is_control() && ch != '\t' {
let safe = safe.get_or_insert_with(|| {
let mut safe = String::with_capacity(text.len());
safe.push_str(&text[..idx]);
safe
});
safe.extend(ch.escape_default());
} else if let Some(safe) = &mut safe {
safe.push(ch);
}
}
safe.map_or(Cow::Borrowed(text), Cow::Owned)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn escape_text_escapes_control_characters() {
assert_eq!(
escape_text("ok\x1b]52;c;bad\x07"),
"ok\\u{1b}]52;c;bad\\u{7}"
);
assert_eq!(escape_text("keeps\ttabs"), "keeps\ttabs");
}
#[test]
fn escape_text_preserves_multibyte_text_around_control_characters() {
assert_eq!(escape_text("å\x1b中"), "å\\u{1b}中");
}
}