@@ -159,26 +159,8 @@ impl Mode {
159
159
}
160
160
}
161
161
162
- fn scan_escape ( first_char : char , chars : & mut Chars < ' _ > , mode : Mode ) -> Result < char , EscapeError > {
163
- if first_char != '\\' {
164
- // Previous character was not a slash, and we don't expect it to be
165
- // an escape-only character.
166
- return match first_char {
167
- '\t' | '\n' => Err ( EscapeError :: EscapeOnlyChar ) ,
168
- '\r' => Err ( EscapeError :: BareCarriageReturn ) ,
169
- '\'' if mode. in_single_quotes ( ) => Err ( EscapeError :: EscapeOnlyChar ) ,
170
- '"' if mode. in_double_quotes ( ) => Err ( EscapeError :: EscapeOnlyChar ) ,
171
- _ => {
172
- if mode. is_bytes ( ) && !first_char. is_ascii ( ) {
173
- // Byte literal can't be a non-ascii character.
174
- return Err ( EscapeError :: NonAsciiCharInByte ) ;
175
- }
176
- Ok ( first_char)
177
- }
178
- } ;
179
- }
180
-
181
- // Previous character is '\\', try to unescape it.
162
+ fn scan_escape ( chars : & mut Chars < ' _ > , mode : Mode ) -> Result < char , EscapeError > {
163
+ // Previous character was '\\', unescape what follows.
182
164
183
165
let second_char = chars. next ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
184
166
@@ -270,9 +252,24 @@ fn scan_escape(first_char: char, chars: &mut Chars<'_>, mode: Mode) -> Result<ch
270
252
Ok ( res)
271
253
}
272
254
255
+ #[ inline]
256
+ fn ascii_check ( first_char : char , mode : Mode ) -> Result < char , EscapeError > {
257
+ if mode. is_bytes ( ) && !first_char. is_ascii ( ) {
258
+ // Byte literal can't be a non-ascii character.
259
+ Err ( EscapeError :: NonAsciiCharInByte )
260
+ } else {
261
+ Ok ( first_char)
262
+ }
263
+ }
264
+
273
265
fn unescape_char_or_byte ( chars : & mut Chars < ' _ > , mode : Mode ) -> Result < char , EscapeError > {
274
266
let first_char = chars. next ( ) . ok_or ( EscapeError :: ZeroChars ) ?;
275
- let res = scan_escape ( first_char, chars, mode) ?;
267
+ let res = match first_char {
268
+ '\\' => scan_escape ( chars, mode) ,
269
+ '\n' | '\t' | '\'' => Err ( EscapeError :: EscapeOnlyChar ) ,
270
+ '\r' => Err ( EscapeError :: BareCarriageReturn ) ,
271
+ _ => ascii_check ( first_char, mode) ,
272
+ } ?;
276
273
if chars. next ( ) . is_some ( ) {
277
274
return Err ( EscapeError :: MoreThanOneChar ) ;
278
275
}
@@ -303,12 +300,14 @@ where
303
300
skip_ascii_whitespace ( & mut chars, start, callback) ;
304
301
continue ;
305
302
}
306
- _ => scan_escape ( first_char , & mut chars, mode) ,
303
+ _ => scan_escape ( & mut chars, mode) ,
307
304
}
308
305
}
309
306
'\n' => Ok ( '\n' ) ,
310
307
'\t' => Ok ( '\t' ) ,
311
- _ => scan_escape ( first_char, & mut chars, mode) ,
308
+ '"' => Err ( EscapeError :: EscapeOnlyChar ) ,
309
+ '\r' => Err ( EscapeError :: BareCarriageReturn ) ,
310
+ _ => ascii_check ( first_char, mode) ,
312
311
} ;
313
312
let end = initial_len - chars. as_str ( ) . len ( ) ;
314
313
callback ( start..end, unescaped_char) ;
0 commit comments