perl-regex 0.13.3

Regex parsing and validation helpers for Perl syntax
Documentation
pub(crate) fn detect_nested_quantifiers(pattern: &str) -> bool {
    let bytes = pattern.as_bytes();
    let mut i = 0;
    let mut group_stack = Vec::new();
    let mut last_type = 0;
    while i < bytes.len() {
        match bytes[i] {
            b'\\' => {
                i += 2;
                last_type = 0;
                continue;
            }
            b'(' => {
                if i + 1 < bytes.len() && bytes[i + 1] == b'?' {
                    i += 2;
                    if i < bytes.len()
                        && matches!(bytes[i], b':' | b'=' | b'!' | b'<' | b'>' | b'|' | b'P' | b'#')
                    {
                        i += 1;
                    }
                } else {
                    i += 1;
                }
                group_stack.push(false);
                last_type = 0;
                continue;
            }
            b')' => {
                if let Some(has_quantifier) = group_stack.pop() {
                    last_type = if has_quantifier { 2 } else { 0 };
                }
            }
            b'+' | b'*' | b'?' | b'{' => {
                if last_type == 2 {
                    if bytes[i] == b'{' {
                        let mut j = i + 1;
                        if is_brace_quantifier(bytes, &mut j) {
                            return true;
                        }
                        last_type = 0;
                        i += 1;
                        continue;
                    }
                    return true;
                }
                if let Some(last) = group_stack.last_mut() {
                    *last = true;
                }
                last_type = 1;
            }
            _ => last_type = 0,
        }
        i += 1;
    }
    false
}

fn is_brace_quantifier(bytes: &[u8], i: &mut usize) -> bool {
    let mut has_digit = false;
    let mut has_comma = false;
    while *i < bytes.len() {
        let ch = bytes[*i];
        *i += 1;
        if ch.is_ascii_digit() {
            has_digit = true;
        } else if ch == b',' && !has_comma {
            has_comma = true;
        } else if ch == b'}' && has_digit {
            return true;
        } else {
            break;
        }
    }
    false
}