Add js-string safe split func
This commit is contained in:
parent
14e2a12dec
commit
3fb62af269
1 changed files with 90 additions and 0 deletions
90
src/utils.rs
Normal file
90
src/utils.rs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/// String safe splitting
|
||||||
|
/// Strings in this case being literal strings in JavaScript source code
|
||||||
|
pub fn str_safe_split(to_split: &str, split_char: char) -> Vec<String> {
|
||||||
|
let mut current_str = String::new();
|
||||||
|
let mut matches = vec![];
|
||||||
|
|
||||||
|
// Doesn't matter what this is. Backslash is only checked while in strings and that is the only reason why this var is used
|
||||||
|
let mut last_char = 'a';
|
||||||
|
// Used for checking if we should exit a string
|
||||||
|
let mut str_open_char = '"';
|
||||||
|
let mut in_string = false;
|
||||||
|
println!("Entering loop");
|
||||||
|
let mut split_iter = to_split.chars().into_iter();
|
||||||
|
while let Some(c) = split_iter.next() {
|
||||||
|
match c {
|
||||||
|
'\'' => {
|
||||||
|
if in_string && str_open_char == '\'' && last_char != '\\' {
|
||||||
|
in_string = false;
|
||||||
|
println!("Exiting string quoted with '");
|
||||||
|
}
|
||||||
|
else if !in_string {
|
||||||
|
str_open_char = '\'';
|
||||||
|
in_string = true;
|
||||||
|
println!("Entered string quoted with '");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'"' => {
|
||||||
|
if in_string && str_open_char == '"' && last_char != '\\' {
|
||||||
|
println!("Exiting string quoted with \"");
|
||||||
|
in_string = false;
|
||||||
|
}
|
||||||
|
else if !in_string {
|
||||||
|
str_open_char = '"';
|
||||||
|
in_string = true;
|
||||||
|
println!("Entered string quoted with \"");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'`' => {
|
||||||
|
if in_string && str_open_char == '`' && last_char != '\\' {
|
||||||
|
in_string = false;
|
||||||
|
println!("Exiting string quoted with `");
|
||||||
|
}
|
||||||
|
else if !in_string {
|
||||||
|
str_open_char = '`';
|
||||||
|
in_string = true;
|
||||||
|
println!("Entered string quoted with `");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
last_char = c.clone();
|
||||||
|
if in_string {
|
||||||
|
current_str.push(c.clone());
|
||||||
|
} else {
|
||||||
|
if c == split_char {
|
||||||
|
matches.push(current_str);
|
||||||
|
current_str = String::new();
|
||||||
|
} else {
|
||||||
|
current_str.push(c.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matches.push(current_str);
|
||||||
|
matches
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_str_safe_split_1() {
|
||||||
|
let res = str_safe_split("this is a test", ' ');
|
||||||
|
assert_eq!(res, vec!["this","is","a","test"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_str_safe_split_2() {
|
||||||
|
let res = str_safe_split("Quote \"test one\"", ' ');
|
||||||
|
assert_eq!(res, vec!["Quote", "\"test one\""]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_str_safe_split_3() {
|
||||||
|
let res = str_safe_split("Quote \"test one\" with 'more quotes' and '`even quotes` in quotes'", ' ');
|
||||||
|
assert_eq!(res, vec!["Quote", "\"test one\"", "with", "'more quotes'", "and", "'`even quotes` in quotes'"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_str_safe_split_4() {
|
||||||
|
let res = str_safe_split("Unfinished 'quote", ' ');
|
||||||
|
assert_eq!(res, vec!["Unfinished", "'quote"]);
|
||||||
|
}
|
Loading…
Reference in a new issue