From 3fb62af26962b36685a93edbe640698e7f9ede17 Mon Sep 17 00:00:00 2001 From: mStar aka a person <12024604-mstarongitlab@users.noreply.gitlab.com> Date: Sat, 9 Mar 2024 20:29:10 +0100 Subject: [PATCH] Add js-string safe split func --- src/utils.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/utils.rs diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..7bbaded --- /dev/null +++ b/src/utils.rs @@ -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 { + 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"]); +} \ No newline at end of file