@@ -1271,6 +1271,98 @@ impl Literal {
12711271 pub unsafe fn from_str_unchecked ( repr : & str ) -> Self {
12721272 Literal :: _new ( unsafe { imp:: Literal :: from_str_unchecked ( repr) } )
12731273 }
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+ }
12741366}
12751367
12761368impl FromStr for Literal {
0 commit comments