|  | #[derive(Clone, Copy, Eq, PartialEq)] | 
|  | enum State { | 
|  | /// The state after seeing a `\`. | 
|  | Escape, | 
|  | /// The state after seeing a `\x`. | 
|  | HexFirst, | 
|  | /// The state after seeing a `\x[0-9A-Fa-f]`. | 
|  | HexSecond(char), | 
|  | /// Default state. | 
|  | Literal, | 
|  | } | 
|  |  | 
|  | pub fn unescape(s: &str) -> Vec<u8> { | 
|  | use self::State::*; | 
|  |  | 
|  | let mut bytes = vec![]; | 
|  | let mut state = Literal; | 
|  | for c in s.chars() { | 
|  | match state { | 
|  | Escape => match c { | 
|  | '\\' => { | 
|  | bytes.push(b'\\'); | 
|  | state = Literal; | 
|  | } | 
|  | 'n' => { | 
|  | bytes.push(b'\n'); | 
|  | state = Literal; | 
|  | } | 
|  | 'r' => { | 
|  | bytes.push(b'\r'); | 
|  | state = Literal; | 
|  | } | 
|  | 't' => { | 
|  | bytes.push(b'\t'); | 
|  | state = Literal; | 
|  | } | 
|  | 'x' => { | 
|  | state = HexFirst; | 
|  | } | 
|  | c => { | 
|  | bytes.extend(format!(r"\{}", c).into_bytes()); | 
|  | state = Literal; | 
|  | } | 
|  | }, | 
|  | HexFirst => match c { | 
|  | '0'..='9' | 'A'..='F' | 'a'..='f' => { | 
|  | state = HexSecond(c); | 
|  | } | 
|  | c => { | 
|  | bytes.extend(format!(r"\x{}", c).into_bytes()); | 
|  | state = Literal; | 
|  | } | 
|  | }, | 
|  | HexSecond(first) => match c { | 
|  | '0'..='9' | 'A'..='F' | 'a'..='f' => { | 
|  | let ordinal = format!("{}{}", first, c); | 
|  | let byte = u8::from_str_radix(&ordinal, 16).unwrap(); | 
|  | bytes.push(byte); | 
|  | state = Literal; | 
|  | } | 
|  | c => { | 
|  | let original = format!(r"\x{}{}", first, c); | 
|  | bytes.extend(original.into_bytes()); | 
|  | state = Literal; | 
|  | } | 
|  | }, | 
|  | Literal => match c { | 
|  | '\\' => { | 
|  | state = Escape; | 
|  | } | 
|  | c => { | 
|  | bytes.extend(c.to_string().as_bytes()); | 
|  | } | 
|  | }, | 
|  | } | 
|  | } | 
|  | match state { | 
|  | Escape => bytes.push(b'\\'), | 
|  | HexFirst => bytes.extend(b"\\x"), | 
|  | HexSecond(c) => bytes.extend(format!("\\x{}", c).into_bytes()), | 
|  | Literal => {} | 
|  | } | 
|  | bytes | 
|  | } |