use std::path::Path;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EscapedDisplayText {
value: String,
}
impl EscapedDisplayText {
#[must_use]
pub fn from_display_text(text: impl AsRef<str>) -> Self {
let mut value = String::new();
for character in text.as_ref().chars() {
append_display_character(&mut value, character);
}
Self { value }
}
#[must_use]
pub fn from_path(path: &Path) -> Self {
Self::from_display_text(path.to_string_lossy())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.value
}
}
fn append_display_character(output: &mut String, character: char) {
match character {
'\\' => output.push_str("\\\\"),
'"' => output.push_str("\\\""),
'\n' => output.push_str("\\n"),
'\r' => output.push_str("\\r"),
'\t' => output.push_str("\\t"),
character if character.is_control() || is_bidi_control(character) => {
use std::fmt::Write as _;
let _written = write!(output, "\\u{{{:X}}}", u32::from(character));
}
character => output.push(character),
}
}
const fn is_bidi_control(character: char) -> bool {
matches!(
character,
'\u{061C}'
| '\u{200E}'
| '\u{200F}'
| '\u{202A}'..='\u{202E}'
| '\u{2066}'..='\u{2069}'
)
}