1pub fn unescape(s: &str) -> Option<String> {2 let mut chars = s.chars();3 let mut out = String::with_capacity(s.len());45 while let Some(c) = chars.next() {6 if c != '\\' {7 out.push(c);8 continue;9 }10 match chars.next()? {11 c @ ('\\' | '"' | '\'') => out.push(c),12 'b' => out.push('\u{0008}'),13 'f' => out.push('\u{000c}'),14 'n' => out.push('\n'),15 'r' => out.push('\r'),16 't' => out.push('\t'),17 'u' => {18 let c = IntoIterator::into_iter([19 chars.next()?,20 chars.next()?,21 chars.next()?,22 chars.next()?,23 ])24 .map(|c| c.to_digit(16))25 .try_fold(0u32, |acc, v| Some((acc << 8) | (v?)))?;26 out.push(char::from_u32(c)?)27 }28 'x' => {29 let c = IntoIterator::into_iter([chars.next()?, chars.next()?])30 .map(|c| c.to_digit(16))31 .try_fold(0u32, |acc, v| Some((acc << 8) | (v?)))?;32 out.push(char::from_u32(c)?)33 }34 _ => return None,35 }36 }37 Some(out)38}