Skip to main content

argyph_parse/
parser.rs

1use crate::error::Result;
2use crate::types::ParsedFile;
3use argyph_fs::{FileEntry, Language};
4use std::str;
5
6/// Parses a single source file with tree-sitter, extracting symbols, AST-aware
7/// chunks, and raw import statements.
8pub trait Parser: Send + Sync {
9    fn parse(&self, file: &FileEntry, source: &str) -> Result<ParsedFile>;
10}
11
12/// The production parser implementation.
13///
14/// Dispatches to the correct language-specific parser based on the file's
15/// detected [`Language`]. Files with unrecognized languages receive a
16/// chunk-only parse (no symbols, no imports).
17pub struct DefaultParser {
18    max_chunk_size: usize,
19}
20
21impl DefaultParser {
22    #[must_use]
23    pub fn new() -> Self {
24        Self {
25            max_chunk_size: 4096,
26        }
27    }
28
29    pub fn set_max_chunk_size(&mut self, size: usize) {
30        self.max_chunk_size = size;
31    }
32}
33
34impl Parser for DefaultParser {
35    fn parse(&self, file: &FileEntry, source: &str) -> Result<ParsedFile> {
36        match file.language {
37            Some(Language::Rust) => crate::languages::parse_rust(file, source, self.max_chunk_size),
38            Some(Language::TypeScript) => {
39                crate::languages::parse_typescript(file, source, self.max_chunk_size)
40            }
41            Some(Language::Python) => {
42                crate::languages::parse_python(file, source, self.max_chunk_size)
43            }
44            _ => {
45                let path = file.path.clone();
46                let chunks = if !source.is_empty() {
47                    crate::chunker::fallback_chunks(
48                        &path,
49                        source,
50                        self.max_chunk_size,
51                        file.language.unwrap_or(Language::Markdown),
52                    )
53                } else {
54                    Vec::new()
55                };
56                Ok(ParsedFile {
57                    symbols: Vec::new(),
58                    chunks,
59                    imports: Vec::new(),
60                })
61            }
62        }
63    }
64}
65
66impl Default for DefaultParser {
67    fn default() -> Self {
68        Self::new()
69    }
70}
71
72#[cfg(test)]
73#[allow(clippy::unwrap_used, clippy::expect_used)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn default_parser_construction() {
79        let parser = DefaultParser::new();
80        assert_eq!(parser.max_chunk_size, 4096);
81    }
82
83    #[test]
84    fn set_max_chunk_size() {
85        let mut parser = DefaultParser::new();
86        parser.set_max_chunk_size(1024);
87        assert_eq!(parser.max_chunk_size, 1024);
88    }
89}