sniff-cli 0.1.1

An exhaustive LLM-backed slop finder for codebases
Documentation
fn skip_ws(bytes: &[u8], mut idx: usize) -> usize {
    while idx < bytes.len() && bytes[idx].is_ascii_whitespace() {
        idx += 1;
    }
    idx
}

fn read_ident_end(bytes: &[u8], mut idx: usize) -> usize {
    while idx < bytes.len() && (bytes[idx].is_ascii_alphanumeric() || bytes[idx] == b'_') {
        idx += 1;
    }
    idx
}

fn starts_with_double_colon(bytes: &[u8], idx: usize) -> bool {
    idx + 1 < bytes.len() && bytes[idx] == b':' && bytes[idx + 1] == b':'
}

fn scan_namespace_chain(line: &str, bytes: &[u8], start: usize) -> Option<(String, usize)> {
    let mut cursor = start;
    let mut parts = Vec::new();

    while starts_with_double_colon(bytes, cursor) {
        cursor += 2;
        cursor = skip_ws(bytes, cursor);
        let seg_start = cursor;
        cursor = read_ident_end(bytes, cursor);
        if seg_start == cursor {
            break;
        }
        parts.push(&line[seg_start..cursor]);
        cursor = skip_ws(bytes, cursor);
    }

    if parts.is_empty() {
        None
    } else {
        Some((parts.join("::"), cursor))
    }
}

fn advance_member_path(line: &str, bytes: &[u8], mut cursor: usize) -> (String, usize) {
    let mut last_member = String::new();
    let mut last_cursor = cursor;

    loop {
        cursor = skip_ws(bytes, cursor);
        if cursor >= bytes.len() || bytes[cursor] != b'.' {
            break;
        }

        cursor += 1;
        cursor = skip_ws(bytes, cursor);
        let seg_start = cursor;
        cursor = read_ident_end(bytes, cursor);
        if seg_start == cursor {
            break;
        }
        last_member.clear();
        last_member.push_str(&line[seg_start..cursor]);
        last_cursor = cursor;
    }

    (last_member, last_cursor)
}

fn scan_member_chain(line: &str, bytes: &[u8], start: usize) -> Option<(String, usize)> {
    let mut cursor = skip_ws(bytes, start);
    let member_start = cursor;
    cursor = read_ident_end(bytes, cursor);

    if member_start >= cursor {
        return None;
    }

    let lookahead = skip_ws(bytes, cursor);
    if lookahead < bytes.len() && bytes[lookahead] == b'.' {
        let (last_member, last_cursor) = advance_member_path(line, bytes, lookahead);
        let call_cursor = skip_ws(bytes, last_cursor);
        if call_cursor < bytes.len() && bytes[call_cursor] == b'(' {
            return Some((last_member, call_cursor));
        }
    } else if lookahead < bytes.len() && bytes[lookahead] == b'(' {
        return Some((line[member_start..cursor].to_string(), lookahead));
    }

    None
}

pub(crate) fn collect_refs(line: &str) -> Vec<String> {
    let mut refs = Vec::new();
    let bytes = line.as_bytes();
    let mut i = 0usize;
    while i < bytes.len() {
        if !(bytes[i].is_ascii_alphabetic() || bytes[i] == b'_') {
            i += 1;
            continue;
        }

        let start = i;
        i += 1;
        while i < bytes.len() && (bytes[i].is_ascii_alphanumeric() || bytes[i] == b'_') {
            i += 1;
        }
        let ident = &line[start..i];
        let mut j = i;
        while j < bytes.len() && bytes[j].is_ascii_whitespace() {
            j += 1;
        }

        if starts_with_double_colon(bytes, j) {
            if let Some((chain, cursor)) = scan_namespace_chain(line, bytes, j) {
                refs.push(format!("{}::{}", ident, chain));
                i = cursor;
                continue;
            }
        } else if j < bytes.len() && bytes[j] == b'.' {
            if let Some((member, cursor)) = scan_member_chain(line, bytes, j + 1) {
                refs.push(member);
                i = cursor;
                continue;
            }
        } else if j < bytes.len() && bytes[j] == b'(' {
            refs.push(ident.to_string());
            continue;
        }
    }
    refs
}