Created
October 18, 2018 17:25
-
-
Save dvdhrm/5a951931e47479f53dd03b1e0fe9a1e6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn unquote_single<'a>(acc: &mut String, source: &'a str) -> Option<&'a str> { | |
if let Some(end) = source.find('\'') { | |
acc.push_str(&source[..end]); | |
Some(&source[end + 1..]) | |
} else { | |
None | |
} | |
} | |
fn unquote_double<'a>(acc: &mut String, source: &'a str) -> Option<&'a str> { | |
None | |
} | |
fn unquote_escape<'a>(acc: &mut String, source: &'a str) -> Option<&'a str> { | |
None | |
} | |
fn unquote(mut source: &str) -> Option<String> { | |
let mut acc = String::with_capacity(source.len() / 2); | |
// | |
// Unstable `std::String` allows passing a `&[char]` instead of the closure to find(), and | |
// it will search for any occurance of any character provided in the slice. This is still | |
// unstable and hidden behind the 'pattern' RFC. | |
// Note that it is very likely implemented similarly to the closure we use here, so we | |
// should be good. Maybe in the future someone will fallback to an optimized `strspn(3)`. | |
// | |
while let Some(idx) = source.find(|c| (c == '\'' || c == '"' || c == '\\')) { | |
// | |
// Push anything up to the first quote/escape literally. Then depending on the | |
// following character perform the required unquote operation. Update `source` to | |
// point to the next character to continue with. | |
// | |
let (front, tail) = source.split_at(idx); | |
let mut i_tail = tail.chars(); | |
let op = i_tail.next(); | |
acc.push_str(front); | |
source = i_tail.as_str(); | |
source = match op { | |
Some('\'') => unquote_single(&mut acc, source)?, | |
Some('"') => unquote_double(&mut acc, source)?, | |
Some('\\') => unquote_escape(&mut acc, source)?, | |
_ => panic!(), | |
}; | |
} | |
acc.push_str(source); | |
Some(acc) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment