git-topology 0.1.2

Shared clustering and topology primitives for git-cognitive and git-semantic
Documentation
pub mod languages;
pub mod parser;

pub use parser::parse;

use anyhow::Result;

#[derive(Debug, Clone)]
pub struct CodeChunk {
    pub text: String,
    pub start_line: usize,
    pub end_line: usize,
}

pub fn chunk_code(text: &str, file_path: Option<&str>) -> Result<Vec<CodeChunk>> {
    if let Some(path) = file_path {
        if let Some(language) = languages::detect_language(path) {
            return parser::parse_with_tree_sitter(text, language);
        }
    }

    Ok(vec![CodeChunk {
        text: text.to_string(),
        start_line: 0,
        end_line: text.lines().count(),
    }])
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn chunk_unsupported_language_returns_whole_file() {
        let text = "hello world\nfoo bar\n";
        let chunks = chunk_code(text, Some("file.txt")).unwrap();
        assert_eq!(chunks.len(), 1);
        assert_eq!(chunks[0].text, text);
        assert_eq!(chunks[0].start_line, 0);
    }

    #[test]
    fn chunk_no_path_returns_whole_file() {
        let text = "fn main() {}";
        let chunks = chunk_code(text, None).unwrap();
        assert_eq!(chunks.len(), 1);
    }

    #[test]
    fn chunk_rust_finds_functions() {
        let code = "fn foo() { let x = 1; }\nfn bar() { let y = 2; }\n";
        let chunks = chunk_code(code, Some("src/main.rs")).unwrap();
        assert!(chunks.len() >= 2);
    }

    #[test]
    fn chunk_python_finds_functions() {
        let code = "def foo():\n    pass\n\ndef bar():\n    pass\n";
        let chunks = chunk_code(code, Some("main.py")).unwrap();
        assert!(chunks.len() >= 2);
    }

    #[test]
    fn chunk_lines_are_ordered() {
        let code = "fn a() {}\nfn b() {}\nfn c() {}\n";
        let chunks = chunk_code(code, Some("lib.rs")).unwrap();
        let starts: Vec<usize> = chunks.iter().map(|c| c.start_line).collect();
        let mut sorted = starts.clone();
        sorted.sort();
        assert_eq!(starts, sorted);
    }
}