opencrates 3.0.1

Enterprise-grade AI-powered Rust development companion with comprehensive automation, monitoring, and deployment capabilities
/// A small utility that looks for `needle` in the `haystack`, starting from
/// `start_pos`. Returns `Some(index)` of the first match, or `None` if the
/// sequence is not found.
pub fn seek_sequence(
    haystack: &[String],
    needle: &[String],
    start_pos: usize,
    is_end_of_file: bool,
) -> Option<usize> {
    if needle.is_empty() {
        return None;
    }

    if is_end_of_file && haystack.ends_with(needle) {
        return Some(haystack.len() - needle.len());
    }

    // First pass: exact match.
    if let Some(pos) = haystack[start_pos..]
        .windows(needle.len())
        .position(|window| window == needle)
    {
        return Some(start_pos + pos);
    }

    // Second pass: if the first pass failed, try a "fuzzy" match that
    // normalises some common punctuation differences.
    let needle_norm: Vec<String> = needle.iter().map(|s| normalize_for_match(s)).collect();
    if let Some(pos) = haystack[start_pos..]
        .windows(needle.len())
        .position(|window| {
            let window_norm: Vec<String> = window.iter().map(|s| normalize_for_match(s)).collect();
            window_norm == needle_norm
        })
    {
        return Some(start_pos + pos);
    }

    None
}

/// Normalises a string for fuzzy matching.
///  - Trims leading/trailing whitespace.
///  - Replaces various dash-like characters with a standard hyphen.
fn normalize_for_match(s: &str) -> String {
    s.trim()
        .replace(['\u{2013}', '\u{2014}', '\u{2015}'], "-") // En dash, em dash, horizontal bar
        .replace('\u{2011}', "-") // Non-breaking hyphen
}