@@ -1271,6 +1271,98 @@ impl Literal {
1271
1271
pub unsafe fn from_str_unchecked ( repr : & str ) -> Self {
1272
1272
Literal :: _new ( unsafe { imp:: Literal :: from_str_unchecked ( repr) } )
1273
1273
}
1274
+
1275
+ /// Returns the unescaped string value if the current literal is a string or a string literal.
1276
+ #[ cfg( procmacro2_semver_exempt) ]
1277
+ pub fn str_value ( & self ) -> Result < String , proc_macro:: ConversionErrorKind > {
1278
+ match self . inner {
1279
+ imp:: Literal :: Compiler ( ref compiler_lit) => compiler_lit. str_value ( ) ,
1280
+ imp:: Literal :: Fallback ( ref fallback) => {
1281
+ if !fallback. repr . starts_with ( '"' ) {
1282
+ return Err ( proc_macro:: ConversionErrorKind :: InvalidLiteralKind ) ;
1283
+ }
1284
+ let mut error = None ;
1285
+ let mut buf = String :: with_capacity ( fallback. repr . len ( ) ) ;
1286
+ rustc_literal_escaper:: unescape_str ( & fallback. repr , |_, res| match res {
1287
+ Ok ( c) => buf. push ( c) ,
1288
+ Err ( err) => {
1289
+ if err. is_fatal ( ) {
1290
+ error = Some ( ConversionErrorKind :: FailedToUnescape ( err) ) ;
1291
+ }
1292
+ }
1293
+ } ) ;
1294
+ if let Some ( error) = error {
1295
+ Err ( error)
1296
+ } else {
1297
+ Ok ( buf)
1298
+ }
1299
+ }
1300
+ }
1301
+ }
1302
+
1303
+ /// Returns the unescaped string value if the current literal is a c-string or a c-string
1304
+ /// literal.
1305
+ #[ cfg( procmacro2_semver_exempt) ]
1306
+ pub fn cstr_value ( & self ) -> Result < Vec < u8 > , proc_macro:: ConversionErrorKind > {
1307
+ match self . inner {
1308
+ imp:: Literal :: Compiler ( ref compiler_lit) => compiler_lit. cstr_value ( ) ,
1309
+ imp:: Literal :: Fallback ( ref fallback) => {
1310
+ if !fallback. repr . starts_with ( 'c' ) {
1311
+ return Err ( proc_macro:: ConversionErrorKind :: InvalidLiteralKind ) ;
1312
+ }
1313
+ let mut error = None ;
1314
+ let mut buf = Vec :: with_capacity ( symbol. len ( ) ) ;
1315
+
1316
+ rustc_literal_escaper:: unescape_c_str ( symbol, |_span, res| match res {
1317
+ Ok ( MixedUnit :: Char ( c) ) => {
1318
+ buf. extend_from_slice ( c. get ( ) . encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) )
1319
+ }
1320
+ Ok ( MixedUnit :: HighByte ( b) ) => buf. push ( b. get ( ) ) ,
1321
+ Err ( err) => {
1322
+ if err. is_fatal ( ) {
1323
+ error = Some ( ConversionErrorKind :: FailedToUnescape ( err) ) ;
1324
+ }
1325
+ }
1326
+ } ) ;
1327
+ if let Some ( error) = error {
1328
+ Err ( error)
1329
+ } else {
1330
+ buf. push ( 0 ) ;
1331
+ Ok ( buf)
1332
+ }
1333
+ }
1334
+ }
1335
+ }
1336
+
1337
+ /// Returns the unescaped string value if the current literal is a byte string or a byte string
1338
+ /// literal.
1339
+ #[ cfg( procmacro2_semver_exempt) ]
1340
+ pub fn byte_str_value ( & self ) -> Result < Vec < u8 > , proc_macro:: ConversionErrorKind > {
1341
+ match self . inner {
1342
+ imp:: Literal :: Compiler ( ref compiler_lit) => compiler_lit. byte_str_value ( ) ,
1343
+ imp:: Literal :: Fallback ( ref fallback) => {
1344
+ if !fallback. repr . starts_with ( 'c' ) {
1345
+ return Err ( proc_macro:: ConversionErrorKind :: InvalidLiteralKind ) ;
1346
+ }
1347
+ let mut error = None ;
1348
+ let mut buf = Vec :: with_capacity ( symbol. len ( ) ) ;
1349
+
1350
+ rustc_literal_escaper:: unescape_byte_str ( symbol, |_span, res| match res {
1351
+ Ok ( c) => buf. push ( c) ,
1352
+ Err ( err) => {
1353
+ if err. is_fatal ( ) {
1354
+ error = Some ( ConversionErrorKind :: FailedToUnescape ( err) ) ;
1355
+ }
1356
+ }
1357
+ } ) ;
1358
+ if let Some ( error) = error {
1359
+ Err ( error)
1360
+ } else {
1361
+ Ok ( buf)
1362
+ }
1363
+ }
1364
+ }
1365
+ }
1274
1366
}
1275
1367
1276
1368
impl FromStr for Literal {
0 commit comments