Skip to content

Commit

Permalink
deduplicate unescape_unicode implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
JasperDeSutter committed Dec 21, 2022
1 parent 93b1ad7 commit 8820caf
Showing 1 changed file with 23 additions and 40 deletions.
63 changes: 23 additions & 40 deletions fluent-syntax/src/unicode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ fn encode_unicode(s: Option<&str>) -> char {
/// assert_eq!(s, "Foo 😊 Bar");
/// ```
pub fn unescape_unicode<W>(w: &mut W, input: &str) -> fmt::Result
where
W: fmt::Write,
{
if unescape(w, input)? {
return Ok(());
}
w.write_str(input)
}

fn unescape<W>(w: &mut W, input: &str) -> Result<bool, std::fmt::Error>
where
W: fmt::Write,
{
Expand All @@ -79,9 +89,7 @@ where
ptr += 1;
continue;
}
if start != ptr {
w.write_str(&input[start..ptr])?;
}
w.write_str(&input[start..ptr])?;

ptr += 1;

Expand All @@ -100,10 +108,15 @@ where
w.write_char(new_char)?;
start = ptr;
}

if start == 0 {
return Ok(false);
}

if start != ptr {
w.write_str(&input[start..ptr])?;
}
Ok(())
Ok(true)
}

/// Unescapes to a `Cow<str>` optionally allocating.
Expand All @@ -119,41 +132,11 @@ where
/// );
/// ```
pub fn unescape_unicode_to_string(input: &str) -> Cow<str> {
let bytes = input.as_bytes();
let mut result = Cow::from(input);

let mut ptr = 0;

while let Some(b) = bytes.get(ptr) {
if b != &b'\\' {
if let Cow::Owned(ref mut s) = result {
s.push(*b as char);
}
ptr += 1;
continue;
}

if let Cow::Borrowed(_) = result {
result = Cow::from(&input[0..ptr]);
}

ptr += 1;

let new_char = match bytes.get(ptr) {
Some(b'\\') => '\\',
Some(b'"') => '"',
Some(u @ b'u') | Some(u @ b'U') => {
let start = ptr + 1;
let len = if u == &b'u' { 4 } else { 6 };
ptr += len;
input
.get(start..(start + len))
.map_or(UNKNOWN_CHAR, |slice| encode_unicode(Some(slice)))
}
_ => UNKNOWN_CHAR,
};
result.to_mut().push(new_char);
ptr += 1;
let mut result = String::new();
let owned = unescape(&mut result, input).expect("String write methods don't Err");
if owned {
Cow::Owned(result)
} else {
Cow::Borrowed(input)
}
result
}

0 comments on commit 8820caf

Please sign in to comment.