pub fn tokenize_comp_references(inside: &str, verbose: bool) -> Result<Vec<String>, String> {
let mut refs = Vec::new();
let mut current = String::new();
let mut in_quotes = false;
let mut quote_char = '\0';
let mut bracket_depth = 0;
let mut paren_depth = 0;
for ch in inside.chars() {
match ch {
'"' | '\'' | '`' => {
current.push(ch);
if in_quotes && quote_char == ch {
in_quotes = false;
} else if !in_quotes {
in_quotes = true;
quote_char = ch;
}
}
'(' => { current.push(ch); if !in_quotes { paren_depth += 1; } }
')' => { current.push(ch); if !in_quotes && paren_depth > 0 { paren_depth -= 1; } }
'[' => { current.push(ch); if !in_quotes { bracket_depth += 1; } }
']' => { current.push(ch); if !in_quotes && bracket_depth > 0 { bracket_depth -= 1; } }
',' => {
if !in_quotes && bracket_depth == 0 && paren_depth == 0 {
let t = current.trim();
if !t.is_empty() { refs.push(t.to_string()); }
current.clear();
} else {
current.push(ch);
}
}
_ => current.push(ch),
}
}
let t = current.trim();
if !t.is_empty() { refs.push(t.to_string()); }
if in_quotes { return Err("Unmatched quotes in comp(...) references".to_string()); }
if verbose { eprintln!("[tokenize_comp_references] => {:?}", refs); }
Ok(refs)
}
pub fn tokenize_pick_args(source: &str, verbose: bool) -> Result<Vec<String>, String> {
let mut parts = Vec::new();
let mut current = String::new();
let mut in_quotes = false;
let mut quote_char = '\0';
let mut bracket_depth = 0;
let mut paren_depth = 0;
let mut in_arrow_lambda = false;
let mut arrow_paren_depth = 0;
let chars: Vec<char> = source.chars().collect();
let mut i = 0;
while i < chars.len() {
let ch = chars[i];
match ch {
'"' | '\'' | '`' => {
current.push(ch);
if in_quotes && quote_char == ch {
in_quotes = false;
} else if !in_quotes {
in_quotes = true;
quote_char = ch;
}
}
'(' => { current.push(ch); if !in_quotes { paren_depth += 1; if in_arrow_lambda { arrow_paren_depth += 1; } } }
')' => { current.push(ch); if !in_quotes && paren_depth > 0 { paren_depth -= 1; if in_arrow_lambda && arrow_paren_depth > 0 { arrow_paren_depth -= 1; } } }
'[' => { current.push(ch); if !in_quotes { bracket_depth += 1; } }
']' => { current.push(ch); if !in_quotes && bracket_depth > 0 { bracket_depth -= 1; } }
'=' => {
if !in_quotes && i + 1 < chars.len() && chars[i + 1] == '>' {
current.push('=');
current.push('>');
i += 1;
in_arrow_lambda = true;
arrow_paren_depth = 0;
} else if !in_quotes && i + 1 < chars.len() && chars[i + 1] == '=' {
current.push('=');
current.push('=');
i += 1;
} else {
current.push(ch);
}
}
'>' | '<' => {
if !in_quotes && i + 1 < chars.len() && chars[i + 1] == '=' {
current.push(ch);
current.push('=');
i += 1;
} else {
current.push(ch);
}
}
',' => {
if !in_quotes && bracket_depth == 0 && paren_depth == 0 && !in_arrow_lambda {
let t = current.trim();
if !t.is_empty() { parts.push(t.to_string()); }
current.clear();
} else if !in_quotes && in_arrow_lambda && arrow_paren_depth == 0 {
let t = current.trim();
if !t.is_empty() { parts.push(t.to_string()); }
current.clear();
in_arrow_lambda = false;
} else {
current.push(ch);
}
}
_ => current.push(ch),
}
i += 1;
}
let leftover = current.trim();
if !leftover.is_empty() { parts.push(leftover.to_string()); }
if in_quotes { return Err("Unmatched quotes in function-call arguments".to_string()); }
if verbose { eprintln!("[tokenize_pick_args] => {:?}", parts); }
Ok(parts)
}
pub fn tokenize_bracket_contents(contents: &str, verbose: bool) -> Result<Vec<String>, String> {
let mut tokens = Vec::new();
let mut current = String::new();
let mut in_quotes = false;
let mut quote_char = '\0';
let mut bracket_depth = 0;
let mut paren_depth = 0;
let chars: Vec<char> = contents.chars().collect();
let mut i = 0;
while i < chars.len() {
let ch = chars[i];
match ch {
'"' | '\'' | '`' => {
current.push(ch);
if in_quotes && quote_char == ch {
in_quotes = false;
} else if !in_quotes {
in_quotes = true;
quote_char = ch;
}
}
'(' => { current.push(ch); if !in_quotes { paren_depth += 1; } }
')' => { current.push(ch); if !in_quotes && paren_depth > 0 { paren_depth -= 1; } }
'[' => { current.push(ch); if !in_quotes { bracket_depth += 1; } }
']' => { current.push(ch); if !in_quotes && bracket_depth > 0 { bracket_depth -= 1; } }
',' => {
if !in_quotes && bracket_depth == 0 && paren_depth == 0 {
let t = current.trim();
if !t.is_empty() { tokens.push(t.to_string()); }
current.clear();
} else {
current.push(ch);
}
}
_ => current.push(ch),
}
i += 1;
}
let leftover = current.trim();
if !leftover.is_empty() { tokens.push(leftover.to_string()); }
if in_quotes { return Err("Unmatched quotes in bracket contents".to_string()); }
if verbose { eprintln!("[tokenize_bracket_contents] => {:?}", tokens); }
Ok(tokens)
}