@@ -6,7 +6,7 @@ use std::{
6
6
} ;
7
7
8
8
use rustc_lexer:: unescape:: {
9
- unescape_byte, unescape_char, unescape_mixed, unescape_unicode, MixedUnit , Mode ,
9
+ unescape_byte, unescape_char, unescape_mixed, unescape_unicode, EscapeError , MixedUnit , Mode ,
10
10
} ;
11
11
12
12
use crate :: {
@@ -180,10 +180,7 @@ pub trait IsString: AstToken {
180
180
fn close_quote_text_range ( & self ) -> Option < TextRange > {
181
181
self . quote_offsets ( ) . map ( |it| it. quotes . 1 )
182
182
}
183
- fn escaped_char_ranges (
184
- & self ,
185
- cb : & mut dyn FnMut ( TextRange , Result < char , rustc_lexer:: unescape:: EscapeError > ) ,
186
- ) {
183
+ fn escaped_char_ranges ( & self , cb : & mut dyn FnMut ( TextRange , Result < char , EscapeError > ) ) {
187
184
let text_range_no_quotes = match self . text_range_between_quotes ( ) {
188
185
Some ( it) => it,
189
186
None => return ,
@@ -212,20 +209,17 @@ impl IsString for ast::String {
212
209
}
213
210
214
211
impl ast:: String {
215
- pub fn value ( & self ) -> Option < Cow < ' _ , str > > {
212
+ pub fn value ( & self ) -> Result < Cow < ' _ , str > , EscapeError > {
213
+ let text = self . text ( ) ;
214
+ let text_range = self . text_range_between_quotes ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
215
+ let text = & text[ text_range - self . syntax ( ) . text_range ( ) . start ( ) ] ;
216
216
if self . is_raw ( ) {
217
- let text = self . text ( ) ;
218
- let text =
219
- & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
220
- return Some ( Cow :: Borrowed ( text) ) ;
217
+ return Ok ( Cow :: Borrowed ( text) ) ;
221
218
}
222
219
223
- let text = self . text ( ) ;
224
- let text = & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
225
-
226
220
let mut buf = String :: new ( ) ;
227
221
let mut prev_end = 0 ;
228
- let mut has_error = false ;
222
+ let mut has_error = None ;
229
223
unescape_unicode ( text, Self :: MODE , & mut |char_range, unescaped_char| match (
230
224
unescaped_char,
231
225
buf. capacity ( ) == 0 ,
@@ -239,13 +233,13 @@ impl ast::String {
239
233
buf. push_str ( & text[ ..prev_end] ) ;
240
234
buf. push ( c) ;
241
235
}
242
- ( Err ( _ ) , _) => has_error = true ,
236
+ ( Err ( e ) , _) => has_error = Some ( e ) ,
243
237
} ) ;
244
238
245
239
match ( has_error, buf. capacity ( ) == 0 ) {
246
- ( true , _) => None ,
247
- ( false , true ) => Some ( Cow :: Borrowed ( text) ) ,
248
- ( false , false ) => Some ( Cow :: Owned ( buf) ) ,
240
+ ( Some ( e ) , _) => Err ( e ) ,
241
+ ( None , true ) => Ok ( Cow :: Borrowed ( text) ) ,
242
+ ( None , false ) => Ok ( Cow :: Owned ( buf) ) ,
249
243
}
250
244
}
251
245
}
@@ -256,20 +250,17 @@ impl IsString for ast::ByteString {
256
250
}
257
251
258
252
impl ast:: ByteString {
259
- pub fn value ( & self ) -> Option < Cow < ' _ , [ u8 ] > > {
253
+ pub fn value ( & self ) -> Result < Cow < ' _ , [ u8 ] > , EscapeError > {
254
+ let text = self . text ( ) ;
255
+ let text_range = self . text_range_between_quotes ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
256
+ let text = & text[ text_range - self . syntax ( ) . text_range ( ) . start ( ) ] ;
260
257
if self . is_raw ( ) {
261
- let text = self . text ( ) ;
262
- let text =
263
- & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
264
- return Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
258
+ return Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
265
259
}
266
260
267
- let text = self . text ( ) ;
268
- let text = & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
269
-
270
261
let mut buf: Vec < u8 > = Vec :: new ( ) ;
271
262
let mut prev_end = 0 ;
272
- let mut has_error = false ;
263
+ let mut has_error = None ;
273
264
unescape_unicode ( text, Self :: MODE , & mut |char_range, unescaped_char| match (
274
265
unescaped_char,
275
266
buf. capacity ( ) == 0 ,
@@ -283,13 +274,13 @@ impl ast::ByteString {
283
274
buf. extend_from_slice ( text[ ..prev_end] . as_bytes ( ) ) ;
284
275
buf. push ( c as u8 ) ;
285
276
}
286
- ( Err ( _ ) , _) => has_error = true ,
277
+ ( Err ( e ) , _) => has_error = Some ( e ) ,
287
278
} ) ;
288
279
289
280
match ( has_error, buf. capacity ( ) == 0 ) {
290
- ( true , _) => None ,
291
- ( false , true ) => Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
292
- ( false , false ) => Some ( Cow :: Owned ( buf) ) ,
281
+ ( Some ( e ) , _) => Err ( e ) ,
282
+ ( None , true ) => Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
283
+ ( None , false ) => Ok ( Cow :: Owned ( buf) ) ,
293
284
}
294
285
}
295
286
}
@@ -298,10 +289,7 @@ impl IsString for ast::CString {
298
289
const RAW_PREFIX : & ' static str = "cr" ;
299
290
const MODE : Mode = Mode :: CStr ;
300
291
301
- fn escaped_char_ranges (
302
- & self ,
303
- cb : & mut dyn FnMut ( TextRange , Result < char , rustc_lexer:: unescape:: EscapeError > ) ,
304
- ) {
292
+ fn escaped_char_ranges ( & self , cb : & mut dyn FnMut ( TextRange , Result < char , EscapeError > ) ) {
305
293
let text_range_no_quotes = match self . text_range_between_quotes ( ) {
306
294
Some ( it) => it,
307
295
None => return ,
@@ -322,20 +310,17 @@ impl IsString for ast::CString {
322
310
}
323
311
324
312
impl ast:: CString {
325
- pub fn value ( & self ) -> Option < Cow < ' _ , [ u8 ] > > {
313
+ pub fn value ( & self ) -> Result < Cow < ' _ , [ u8 ] > , EscapeError > {
314
+ let text = self . text ( ) ;
315
+ let text_range = self . text_range_between_quotes ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
316
+ let text = & text[ text_range - self . syntax ( ) . text_range ( ) . start ( ) ] ;
326
317
if self . is_raw ( ) {
327
- let text = self . text ( ) ;
328
- let text =
329
- & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
330
- return Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
318
+ return Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
331
319
}
332
320
333
- let text = self . text ( ) ;
334
- let text = & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
335
-
336
321
let mut buf = Vec :: new ( ) ;
337
322
let mut prev_end = 0 ;
338
- let mut has_error = false ;
323
+ let mut has_error = None ;
339
324
let extend_unit = |buf : & mut Vec < u8 > , unit : MixedUnit | match unit {
340
325
MixedUnit :: Char ( c) => buf. extend ( c. encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) ) ,
341
326
MixedUnit :: HighByte ( b) => buf. push ( b) ,
@@ -353,13 +338,13 @@ impl ast::CString {
353
338
buf. extend ( text[ ..prev_end] . as_bytes ( ) ) ;
354
339
extend_unit ( & mut buf, u) ;
355
340
}
356
- ( Err ( _ ) , _) => has_error = true ,
341
+ ( Err ( e ) , _) => has_error = Some ( e ) ,
357
342
} ) ;
358
343
359
344
match ( has_error, buf. capacity ( ) == 0 ) {
360
- ( true , _) => None ,
361
- ( false , true ) => Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
362
- ( false , false ) => Some ( Cow :: Owned ( buf) ) ,
345
+ ( Some ( e ) , _) => Err ( e ) ,
346
+ ( None , true ) => Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
347
+ ( None , false ) => Ok ( Cow :: Owned ( buf) ) ,
363
348
}
364
349
}
365
350
}
@@ -478,34 +463,34 @@ impl Radix {
478
463
}
479
464
480
465
impl ast:: Char {
481
- pub fn value ( & self ) -> Option < char > {
466
+ pub fn value ( & self ) -> Result < char , EscapeError > {
482
467
let mut text = self . text ( ) ;
483
468
if text. starts_with ( '\'' ) {
484
469
text = & text[ 1 ..] ;
485
470
} else {
486
- return None ;
471
+ return Err ( EscapeError :: ZeroChars ) ;
487
472
}
488
473
if text. ends_with ( '\'' ) {
489
474
text = & text[ 0 ..text. len ( ) - 1 ] ;
490
475
}
491
476
492
- unescape_char ( text) . ok ( )
477
+ unescape_char ( text)
493
478
}
494
479
}
495
480
496
481
impl ast:: Byte {
497
- pub fn value ( & self ) -> Option < u8 > {
482
+ pub fn value ( & self ) -> Result < u8 , EscapeError > {
498
483
let mut text = self . text ( ) ;
499
484
if text. starts_with ( "b\' " ) {
500
485
text = & text[ 2 ..] ;
501
486
} else {
502
- return None ;
487
+ return Err ( EscapeError :: ZeroChars ) ;
503
488
}
504
489
if text. ends_with ( '\'' ) {
505
490
text = & text[ 0 ..text. len ( ) - 1 ] ;
506
491
}
507
492
508
- unescape_byte ( text) . ok ( )
493
+ unescape_byte ( text)
509
494
}
510
495
}
511
496
@@ -559,7 +544,10 @@ mod tests {
559
544
560
545
fn check_string_value < ' a > ( lit : & str , expected : impl Into < Option < & ' a str > > ) {
561
546
assert_eq ! (
562
- ast:: String { syntax: make:: tokens:: literal( & format!( "\" {lit}\" " ) ) } . value( ) . as_deref( ) ,
547
+ ast:: String { syntax: make:: tokens:: literal( & format!( "\" {lit}\" " ) ) }
548
+ . value( )
549
+ . as_deref( )
550
+ . ok( ) ,
563
551
expected. into( )
564
552
) ;
565
553
}
@@ -584,7 +572,8 @@ bcde", "abcde",
584
572
assert_eq ! (
585
573
ast:: ByteString { syntax: make:: tokens:: literal( & format!( "b\" {lit}\" " ) ) }
586
574
. value( )
587
- . as_deref( ) ,
575
+ . as_deref( )
576
+ . ok( ) ,
588
577
expected. into( ) . map( |value| & value[ ..] )
589
578
) ;
590
579
}
0 commit comments