blob: de765901fa0089d1deadf1f2f9e40d73e9ac5621 [file] [log] [blame]
David Tolnay886d8ea2016-09-13 08:34:07 -07001#![cfg(feature = "parsing")]
2
3use nom::{self, IResult};
4
5pub fn escaped_string(input: &str) -> IResult<&str, String> {
6 let mut s = String::new();
7 let mut chars = input.char_indices().peekable();
8 while let Some((byte_offset, ch)) = chars.next() {
9 match ch {
10 '"' => {
11 return IResult::Done(&input[byte_offset..], s);
12 }
13 '\\' => {
14 match chars.next() {
15 Some((_, 'x')) => unimplemented!(),
16 Some((_, 'n')) => s.push('\n'),
17 Some((_, 'r')) => s.push('\r'),
18 Some((_, 't')) => s.push('\t'),
19 Some((_, '\\')) => s.push('\\'),
20 Some((_, '0')) => s.push('\0'),
21 Some((_, 'u')) => unimplemented!(),
22 Some((_, '\'')) => s.push('\''),
23 Some((_, '"')) => s.push('"'),
24 Some((_, '\n')) => {
25 while let Some(&(_, ch)) = chars.peek() {
26 if ch.is_whitespace() {
27 chars.next();
28 } else {
29 break;
30 }
31 }
32 }
33 _ => break,
34 }
35 }
36 ch => {
37 s.push(ch);
38 }
39 }
40 }
41 IResult::Error(nom::Err::Position(nom::ErrorKind::Escaped, input))
42}