Raw string literals
diff --git a/src/escape.rs b/src/escape.rs
index c3b208a..3ff52e3 100644
--- a/src/escape.rs
+++ b/src/escape.rs
@@ -3,7 +3,7 @@
use std::{char, str};
use nom::IResult;
-pub fn escaped_string(input: &str) -> IResult<&str, String> {
+pub fn cooked_string(input: &str) -> IResult<&str, String> {
let mut s = String::new();
let mut chars = input.char_indices().peekable();
while let Some((byte_offset, ch)) = chars.next() {
@@ -48,6 +48,29 @@
IResult::Error
}
+pub fn raw_string(input: &str) -> IResult<&str, (String, usize)> {
+ let mut chars = input.char_indices();
+ let mut n = 0;
+ while let Some((byte_offset, ch)) = chars.next() {
+ match ch {
+ '"' => {
+ n = byte_offset;
+ break;
+ }
+ '#' => {},
+ _ => return IResult::Error,
+ }
+ }
+ while let Some((byte_offset, ch)) = chars.next() {
+ if ch == '"' && input[byte_offset + 1..].starts_with(&input[..n]) {
+ let rest = &input[byte_offset + 1 + n..];
+ let value = &input[n + 1 .. byte_offset];
+ return IResult::Done(rest, (value.to_owned(), n));
+ }
+ }
+ IResult::Error
+}
+
macro_rules! next_char {
($chars:ident @ $pat:pat $(| $rest:pat)*) => {
match $chars.next() {
@@ -101,8 +124,8 @@
}
#[test]
-fn test_escaped_string() {
+fn test_cooked_string() {
let input = r#"\x62 \u{7} \u{64} \u{bf5} \u{12ba} \u{1F395} \u{102345}""#;
let expected = "\x62 \u{7} \u{64} \u{bf5} \u{12ba} \u{1F395} \u{102345}";
- assert_eq!(escaped_string(input), IResult::Done("\"", expected.to_string()));
+ assert_eq!(cooked_string(input), IResult::Done("\"", expected.to_string()));
}