4 fn test_unescape_char_bad() {
5 fn check(literal_text: &str, expected_error: EscapeError) {
6 assert_eq!(unescape_char(literal_text), Err(expected_error));
9 check("", EscapeError::ZeroChars);
10 check(r"\", EscapeError::LoneSlash);
12 check("\n", EscapeError::EscapeOnlyChar);
13 check("\t", EscapeError::EscapeOnlyChar);
14 check("'", EscapeError::EscapeOnlyChar);
15 check("\r", EscapeError::BareCarriageReturn);
17 check("spam", EscapeError::MoreThanOneChar);
18 check(r"\x0ff", EscapeError::MoreThanOneChar);
19 check(r#"\"a"#, EscapeError::MoreThanOneChar);
20 check(r"\na", EscapeError::MoreThanOneChar);
21 check(r"\ra", EscapeError::MoreThanOneChar);
22 check(r"\ta", EscapeError::MoreThanOneChar);
23 check(r"\\a", EscapeError::MoreThanOneChar);
24 check(r"\'a", EscapeError::MoreThanOneChar);
25 check(r"\0a", EscapeError::MoreThanOneChar);
26 check(r"\u{0}x", EscapeError::MoreThanOneChar);
27 check(r"\u{1F63b}}", EscapeError::MoreThanOneChar);
29 check(r"\v", EscapeError::InvalidEscape);
30 check(r"\💩", EscapeError::InvalidEscape);
31 check(r"\●", EscapeError::InvalidEscape);
32 check("\\\r", EscapeError::InvalidEscape);
34 check(r"\x", EscapeError::TooShortHexEscape);
35 check(r"\x0", EscapeError::TooShortHexEscape);
36 check(r"\xf", EscapeError::TooShortHexEscape);
37 check(r"\xa", EscapeError::TooShortHexEscape);
38 check(r"\xx", EscapeError::InvalidCharInHexEscape);
39 check(r"\xы", EscapeError::InvalidCharInHexEscape);
40 check(r"\x🦀", EscapeError::InvalidCharInHexEscape);
41 check(r"\xtt", EscapeError::InvalidCharInHexEscape);
42 check(r"\xff", EscapeError::OutOfRangeHexEscape);
43 check(r"\xFF", EscapeError::OutOfRangeHexEscape);
44 check(r"\x80", EscapeError::OutOfRangeHexEscape);
46 check(r"\u", EscapeError::NoBraceInUnicodeEscape);
47 check(r"\u[0123]", EscapeError::NoBraceInUnicodeEscape);
48 check(r"\u{0x}", EscapeError::InvalidCharInUnicodeEscape);
49 check(r"\u{", EscapeError::UnclosedUnicodeEscape);
50 check(r"\u{0000", EscapeError::UnclosedUnicodeEscape);
51 check(r"\u{}", EscapeError::EmptyUnicodeEscape);
52 check(r"\u{_0000}", EscapeError::LeadingUnderscoreUnicodeEscape);
53 check(r"\u{0000000}", EscapeError::OverlongUnicodeEscape);
54 check(r"\u{FFFFFF}", EscapeError::OutOfRangeUnicodeEscape);
55 check(r"\u{ffffff}", EscapeError::OutOfRangeUnicodeEscape);
56 check(r"\u{ffffff}", EscapeError::OutOfRangeUnicodeEscape);
58 check(r"\u{DC00}", EscapeError::LoneSurrogateUnicodeEscape);
59 check(r"\u{DDDD}", EscapeError::LoneSurrogateUnicodeEscape);
60 check(r"\u{DFFF}", EscapeError::LoneSurrogateUnicodeEscape);
62 check(r"\u{D800}", EscapeError::LoneSurrogateUnicodeEscape);
63 check(r"\u{DAAA}", EscapeError::LoneSurrogateUnicodeEscape);
64 check(r"\u{DBFF}", EscapeError::LoneSurrogateUnicodeEscape);
68 fn test_unescape_char_good() {
69 fn check(literal_text: &str, expected_char: char) {
70 assert_eq!(unescape_char(literal_text), Ok(expected_char));
88 check(r"\x7f", 127 as char);
90 check(r"\u{0}", '\0');
91 check(r"\u{000000}", '\0');
92 check(r"\u{41}", 'A');
93 check(r"\u{0041}", 'A');
94 check(r"\u{00_41}", 'A');
95 check(r"\u{4__1__}", 'A');
96 check(r"\u{1F63b}", '😻');
100 fn test_unescape_str_warn() {
101 fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
102 let mut unescaped = Vec::with_capacity(literal.len());
103 unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
104 assert_eq!(unescaped, expected);
107 // Check we can handle escaped newlines at the end of a file.
114 (0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
115 (3..5, Ok('\u{a0}')),
120 check("\\\n \n x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]);
124 fn test_unescape_str_good() {
125 fn check(literal_text: &str, expected: &str) {
126 let mut buf = Ok(String::with_capacity(literal_text.len()));
127 unescape_literal(literal_text, Mode::Str, &mut |range, c| {
128 if let Ok(b) = &mut buf {
131 Err(e) => buf = Err((range, e)),
135 let buf = buf.as_ref().map(|it| it.as_ref());
136 assert_eq!(buf, Ok(expected))
141 check(" \t\n", " \t\n");
143 check("hello \\\n world", "hello world");
144 check("thread's", "thread's")
148 fn test_unescape_byte_bad() {
149 fn check(literal_text: &str, expected_error: EscapeError) {
150 assert_eq!(unescape_byte(literal_text), Err(expected_error));
153 check("", EscapeError::ZeroChars);
154 check(r"\", EscapeError::LoneSlash);
156 check("\n", EscapeError::EscapeOnlyChar);
157 check("\t", EscapeError::EscapeOnlyChar);
158 check("'", EscapeError::EscapeOnlyChar);
159 check("\r", EscapeError::BareCarriageReturn);
161 check("spam", EscapeError::MoreThanOneChar);
162 check(r"\x0ff", EscapeError::MoreThanOneChar);
163 check(r#"\"a"#, EscapeError::MoreThanOneChar);
164 check(r"\na", EscapeError::MoreThanOneChar);
165 check(r"\ra", EscapeError::MoreThanOneChar);
166 check(r"\ta", EscapeError::MoreThanOneChar);
167 check(r"\\a", EscapeError::MoreThanOneChar);
168 check(r"\'a", EscapeError::MoreThanOneChar);
169 check(r"\0a", EscapeError::MoreThanOneChar);
171 check(r"\v", EscapeError::InvalidEscape);
172 check(r"\💩", EscapeError::InvalidEscape);
173 check(r"\●", EscapeError::InvalidEscape);
175 check(r"\x", EscapeError::TooShortHexEscape);
176 check(r"\x0", EscapeError::TooShortHexEscape);
177 check(r"\xa", EscapeError::TooShortHexEscape);
178 check(r"\xf", EscapeError::TooShortHexEscape);
179 check(r"\xx", EscapeError::InvalidCharInHexEscape);
180 check(r"\xы", EscapeError::InvalidCharInHexEscape);
181 check(r"\x🦀", EscapeError::InvalidCharInHexEscape);
182 check(r"\xtt", EscapeError::InvalidCharInHexEscape);
184 check(r"\u", EscapeError::NoBraceInUnicodeEscape);
185 check(r"\u[0123]", EscapeError::NoBraceInUnicodeEscape);
186 check(r"\u{0x}", EscapeError::InvalidCharInUnicodeEscape);
187 check(r"\u{", EscapeError::UnclosedUnicodeEscape);
188 check(r"\u{0000", EscapeError::UnclosedUnicodeEscape);
189 check(r"\u{}", EscapeError::EmptyUnicodeEscape);
190 check(r"\u{_0000}", EscapeError::LeadingUnderscoreUnicodeEscape);
191 check(r"\u{0000000}", EscapeError::OverlongUnicodeEscape);
193 check("ы", EscapeError::NonAsciiCharInByte);
194 check("🦀", EscapeError::NonAsciiCharInByte);
196 check(r"\u{0}", EscapeError::UnicodeEscapeInByte);
197 check(r"\u{000000}", EscapeError::UnicodeEscapeInByte);
198 check(r"\u{41}", EscapeError::UnicodeEscapeInByte);
199 check(r"\u{0041}", EscapeError::UnicodeEscapeInByte);
200 check(r"\u{00_41}", EscapeError::UnicodeEscapeInByte);
201 check(r"\u{4__1__}", EscapeError::UnicodeEscapeInByte);
202 check(r"\u{1F63b}", EscapeError::UnicodeEscapeInByte);
203 check(r"\u{0}x", EscapeError::UnicodeEscapeInByte);
204 check(r"\u{1F63b}}", EscapeError::UnicodeEscapeInByte);
205 check(r"\u{FFFFFF}", EscapeError::UnicodeEscapeInByte);
206 check(r"\u{ffffff}", EscapeError::UnicodeEscapeInByte);
207 check(r"\u{ffffff}", EscapeError::UnicodeEscapeInByte);
208 check(r"\u{DC00}", EscapeError::UnicodeEscapeInByte);
209 check(r"\u{DDDD}", EscapeError::UnicodeEscapeInByte);
210 check(r"\u{DFFF}", EscapeError::UnicodeEscapeInByte);
211 check(r"\u{D800}", EscapeError::UnicodeEscapeInByte);
212 check(r"\u{DAAA}", EscapeError::UnicodeEscapeInByte);
213 check(r"\u{DBFF}", EscapeError::UnicodeEscapeInByte);
217 fn test_unescape_byte_good() {
218 fn check(literal_text: &str, expected_byte: u8) {
219 assert_eq!(unescape_byte(literal_text), Ok(expected_byte));
224 check(r#"\""#, b'"');
232 check(r"\x00", b'\0');
233 check(r"\x5a", b'Z');
234 check(r"\x5A", b'Z');
242 fn test_unescape_byte_str_good() {
243 fn check(literal_text: &str, expected: &[u8]) {
244 let mut buf = Ok(Vec::with_capacity(literal_text.len()));
245 unescape_literal(literal_text, Mode::ByteStr, &mut |range, c| {
246 if let Ok(b) = &mut buf {
248 Ok(c) => b.push(byte_from_char(c)),
249 Err(e) => buf = Err((range, e)),
253 let buf = buf.as_ref().map(|it| it.as_ref());
254 assert_eq!(buf, Ok(expected))
257 check("foo", b"foo");
259 check(" \t\n", b" \t\n");
261 check("hello \\\n world", b"hello world");
262 check("thread's", b"thread's")
266 fn test_unescape_raw_str() {
267 fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
268 let mut unescaped = Vec::with_capacity(literal.len());
269 unescape_literal(literal, Mode::RawStr, &mut |range, res| unescaped.push((range, res)));
270 assert_eq!(unescaped, expected);
273 check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]);
274 check("\rx", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString)), (1..2, Ok('x'))]);
278 fn test_unescape_raw_byte_str() {
279 fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
280 let mut unescaped = Vec::with_capacity(literal.len());
281 unescape_literal(literal, Mode::RawByteStr, &mut |range, res| unescaped.push((range, res)));
282 assert_eq!(unescaped, expected);
285 check("\r", &[(0..1, Err(EscapeError::BareCarriageReturnInRawString))]);
286 check("🦀", &[(0..4, Err(EscapeError::NonAsciiCharInByte))]);
287 check("🦀a", &[(0..4, Err(EscapeError::NonAsciiCharInByte)), (4..5, Ok('a'))]);