pub fn find_matching_brace(content: &str, open_pos: usize) -> Option<usize> {
let mut depth = 0;
let bytes = content.as_bytes();
for i in open_pos..bytes.len() {
match bytes[i] {
b'{' => depth += 1,
b'}' => {
depth -= 1;
if depth == 0 {
return Some(i);
}
}
_ => {}
}
}
None
}
pub fn extract_braced_content(content: &str, start: usize) -> Option<(String, usize, usize)> {
if let Some(open_pos) = content[start..].find('{') {
let abs_open_pos = start + open_pos;
if let Some(close_pos) = find_matching_brace(content, abs_open_pos) {
let braced_content = content[abs_open_pos..=close_pos].to_string();
return Some((braced_content, abs_open_pos, close_pos));
}
}
None
}
pub fn extract_parenthesized_content(
content: &str,
start: usize,
) -> Option<(String, usize, usize)> {
if let Some(open_pos) = content[start..].find('(') {
let abs_open_pos = start + open_pos;
if let Some(close_pos) = find_matching_paren(content, abs_open_pos) {
let paren_content = content[abs_open_pos..=close_pos].to_string();
return Some((paren_content, abs_open_pos, close_pos));
}
}
None
}
fn find_matching_paren(content: &str, open_pos: usize) -> Option<usize> {
let mut depth = 0;
let bytes = content.as_bytes();
for i in open_pos..bytes.len() {
match bytes[i] {
b'(' => depth += 1,
b')' => {
depth -= 1;
if depth == 0 {
return Some(i);
}
}
_ => {}
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_find_matching_brace() {
let content = "{ foo { bar } baz }";
let close = find_matching_brace(content, 0);
assert_eq!(close, Some(18));
}
#[test]
fn test_extract_braced_content() {
let content = "prefix { inner content } suffix";
let (extracted, start, end) = extract_braced_content(content, 0).unwrap();
assert_eq!(extracted, "{ inner content }");
assert_eq!(start, 7);
assert_eq!(end, 23);
}
#[test]
fn test_extract_parenthesized_content() {
let content = "function(arg1, arg2) { body }";
let (extracted, start, end) = extract_parenthesized_content(content, 0).unwrap();
assert_eq!(extracted, "(arg1, arg2)");
assert_eq!(start, 8);
assert_eq!(end, 19);
}
#[test]
fn test_nested_braces() {
let content = "{ outer { inner { nested } } }";
let close = find_matching_brace(content, 0);
assert_eq!(close, Some(29));
}
}