sniff-cli 0.1.3

An exhaustive LLM-backed slop finder for codebases
Documentation
use crate::config::ResolvedConfig;
use crate::types::FileRecord;

pub(super) async fn parse_files(file_paths: &[String]) -> Result<Vec<FileRecord>, String> {
    let mut file_records = Vec::new();
    for fp in file_paths {
        let fp_clone = fp.clone();
        let record =
            match tokio::task::spawn_blocking(move || crate::parser::parse_file_checked(&fp_clone))
                .await
            {
                Ok(Ok(record)) => record,
                Ok(Err(err)) => return Err(err),
                Err(err) => {
                    return Err(format!("parser task failed for {fp}: {err}"));
                }
            };
        if !record.language.is_empty() {
            file_records.push(record);
        }
    }
    Ok(file_records)
}

pub(super) async fn scan_files(
    path: &str,
    config: &ResolvedConfig,
) -> Result<Vec<FileRecord>, String> {
    let file_paths = crate::walker::walk(path, config)?;
    if file_paths.is_empty() {
        return Ok(Vec::new());
    }

    parse_files(&file_paths).await
}

#[cfg(test)]
mod tests {
    use super::scan_files;
    use crate::config::ResolvedConfig;
    use std::fs;
    use std::time::{SystemTime, UNIX_EPOCH};

    #[tokio::test]
    async fn unsupported_files_are_dropped_from_scan_results() {
        let nanos = SystemTime::now()
            .duration_since(UNIX_EPOCH)
            .unwrap()
            .as_nanos();
        let root = std::env::temp_dir().join(format!("sniff-scan-filter-{nanos}"));
        let src_dir = root.join("src");
        fs::create_dir_all(&src_dir).unwrap();
        fs::write(src_dir.join("note.txt"), "plain text\n").unwrap();
        fs::write(src_dir.join("main.rs"), "fn main() {}\n").unwrap();

        let files = scan_files(root.to_str().unwrap(), &ResolvedConfig::default())
            .await
            .expect("scan should complete");

        assert_eq!(files.len(), 1);
        assert_eq!(files[0].language, "rust");
        assert!(files[0].file_path.ends_with("main.rs"));

        let _ = fs::remove_dir_all(&root);
    }
}