about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJulian Wollersberger <24991778+Julian-Wollersberger@users.noreply.github.com>2020-05-13 09:42:30 +0200
committerJulian Wollersberger <24991778+Julian-Wollersberger@users.noreply.github.com>2020-05-13 09:42:30 +0200
commit1be5d1eabb957c8b0bd0f4564a5f7c8bef1826bb (patch)
tree08bc5f223db3b3bf719a507358be5e10c9f06d87
parente734e31340586f14c29efa6396ae15ad37f84a96 (diff)
downloadrust-1be5d1eabb957c8b0bd0f4564a5f7c8bef1826bb.tar.gz
rust-1be5d1eabb957c8b0bd0f4564a5f7c8bef1826bb.zip
Unified `unescape_{char,byte,str,byte_str,raw_str,raw_byte_str}` methods into one method `unescape_literal` with a mode argument.
-rw-r--r--src/librustc_lexer/src/unescape.rs46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/librustc_lexer/src/unescape.rs b/src/librustc_lexer/src/unescape.rs
index c51bf735fa7..dcb4cc91796 100644
--- a/src/librustc_lexer/src/unescape.rs
+++ b/src/librustc_lexer/src/unescape.rs
@@ -58,6 +58,42 @@ pub enum EscapeError {
     NonAsciiCharInByteString,
 }
 
+/// Takes a contents of a literal (without quotes) and produces a
+/// sequence of escaped characters or errors.
+/// Values are returned through invoking of the provided callback.
+pub fn unescape_literal<F>(literal_text: &str, mode: Mode, callback: &mut F)
+where
+    F: FnMut(Range<usize>, Result<char, EscapeError>),
+{
+    match mode {
+        Mode::Char | Mode::Byte => {
+            let mut chars = literal_text.chars();
+            let result = unescape_char_or_byte(&mut chars, mode);
+            // The Chars iterator moved forward.
+            callback(0..(literal_text.len() - chars.as_str().len()), result);
+        }
+        Mode::Str | Mode::ByteStr => unescape_str_or_byte_str(literal_text, mode, callback),
+        // NOTE: Raw strings do not perform any explicit character escaping, here we
+        // only translate CRLF to LF and produce errors on bare CR.
+        Mode::RawStr | Mode::RawByteStr => {
+            unescape_raw_str_or_byte_str(literal_text, mode, callback)
+        }
+    }
+}
+
+/// Takes a contents of a byte, byte string or raw byte string (without quotes)
+/// and produces a sequence of bytes or errors.
+/// Values are returned through invoking of the provided callback.
+pub fn unescape_byte_literal<F>(literal_text: &str, mode: Mode, callback: &mut F)
+where
+    F: FnMut(Range<usize>, Result<u8, EscapeError>),
+{
+    assert!(mode.is_bytes());
+    unescape_literal(literal_text, mode, &mut |range, result| {
+        callback(range, result.map(byte_from_char));
+    })
+}
+
 /// Takes a contents of a char literal (without quotes), and returns an
 /// unescaped char or an error
 pub fn unescape_char(literal_text: &str) -> Result<char, (usize, EscapeError)> {
@@ -130,13 +166,15 @@ pub enum Mode {
     Str,
     Byte,
     ByteStr,
+    RawStr,
+    RawByteStr,
 }
 
 impl Mode {
     pub fn in_single_quotes(self) -> bool {
         match self {
             Mode::Char | Mode::Byte => true,
-            Mode::Str | Mode::ByteStr => false,
+            Mode::Str | Mode::ByteStr | Mode::RawStr | Mode::RawByteStr => false,
         }
     }
 
@@ -146,8 +184,8 @@ impl Mode {
 
     pub fn is_bytes(self) -> bool {
         match self {
-            Mode::Byte | Mode::ByteStr => true,
-            Mode::Char | Mode::Str => false,
+            Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true,
+            Mode::Char | Mode::Str | Mode::RawStr => false,
         }
     }
 }
@@ -345,7 +383,7 @@ where
 
 fn byte_from_char(c: char) -> u8 {
     let res = c as u32;
-    assert!(res <= u8::max_value() as u32, "guaranteed because of Mode::Byte(Str)");
+    assert!(res <= u8::max_value() as u32, "guaranteed because of Mode::ByteStr");
     res as u8
 }