Skip to main content

garbage_code_hunter/language/
mod.rs

1use std::path::Path;
2
3/// Programming languages supported by the analyzer.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum Language {
6    Rust,
7    C,
8    Cpp,
9    Python,
10    JavaScript,
11    TypeScript,
12    Go,
13    Java,
14    Ruby,
15    Swift,
16    Zig,
17    Unknown,
18}
19
20impl Language {
21    pub fn from_extension(ext: &str) -> Self {
22        match ext {
23            "rs" => Language::Rust,
24            "c" | "h" => Language::C,
25            "cpp" | "cxx" | "cc" | "hpp" | "hh" | "hxx" | "C" | "CPP" => Language::Cpp,
26            "py" => Language::Python,
27            "js" | "mjs" | "cjs" => Language::JavaScript,
28            "ts" | "tsx" | "mts" | "cts" => Language::TypeScript,
29            "go" => Language::Go,
30            "java" => Language::Java,
31            "rb" => Language::Ruby,
32            "swift" => Language::Swift,
33            "zig" => Language::Zig,
34            _ => Language::Unknown,
35        }
36    }
37
38    pub fn from_path(path: &Path) -> Self {
39        path.extension()
40            .and_then(|e| e.to_str())
41            .map(Self::from_extension)
42            .unwrap_or(Language::Unknown)
43    }
44
45    pub fn extensions(&self) -> &'static [&'static str] {
46        match self {
47            Language::Rust => &["rs"],
48            Language::C => &["c", "h"],
49            Language::Cpp => &["cpp", "cxx", "cc", "hpp", "hh", "hxx", "C", "CPP"],
50            Language::Python => &["py"],
51            Language::JavaScript => &["js", "mjs", "cjs"],
52            Language::TypeScript => &["ts", "tsx", "mts", "cts"],
53            Language::Go => &["go"],
54            Language::Java => &["java"],
55            Language::Ruby => &["rb"],
56            Language::Swift => &["swift"],
57            Language::Zig => &["zig"],
58            Language::Unknown => &[],
59        }
60    }
61
62    pub fn display_name(&self) -> &'static str {
63        match self {
64            Language::Rust => "Rust",
65            Language::C => "C",
66            Language::Cpp => "C++",
67            Language::Python => "Python",
68            Language::JavaScript => "JavaScript",
69            Language::TypeScript => "TypeScript",
70            Language::Go => "Go",
71            Language::Java => "Java",
72            Language::Ruby => "Ruby",
73            Language::Swift => "Swift",
74            Language::Zig => "Zig",
75            Language::Unknown => "Unknown",
76        }
77    }
78
79    pub fn line_comment(&self) -> &'static str {
80        match self {
81            Language::Rust
82            | Language::C
83            | Language::Cpp
84            | Language::Go
85            | Language::Java
86            | Language::JavaScript
87            | Language::TypeScript
88            | Language::Ruby
89            | Language::Swift
90            | Language::Zig => "//",
91            Language::Python => "#",
92            Language::Unknown => "//",
93        }
94    }
95
96    pub fn has_tree_sitter_grammar(&self) -> bool {
97        matches!(
98            self,
99            Language::Rust
100                | Language::C
101                | Language::Cpp
102                | Language::Python
103                | Language::JavaScript
104                | Language::TypeScript
105                | Language::Go
106                | Language::Java
107                | Language::Ruby
108                | Language::Swift
109                | Language::Zig
110        )
111    }
112}
113
114/// All languages with a compiled tree-sitter grammar available.
115pub const LANGUAGES_WITH_GRAMMAR: &[Language] = &[
116    Language::Rust,
117    Language::Python,
118    Language::JavaScript,
119    Language::TypeScript,
120    Language::Go,
121    Language::Java,
122    Language::Ruby,
123    Language::Swift,
124    Language::Zig,
125    Language::C,
126    Language::Cpp,
127];
128
129/// All supported source file extensions for discovery.
130pub const SUPPORTED_EXTENSIONS: &[&str] = &[
131    "rs", "c", "h", "cpp", "cxx", "cc", "hpp", "hh", "hxx", "C", "CPP", "py", "js", "mjs", "cjs",
132    "ts", "tsx", "mts", "cts", "go", "java", "rb", "swift", "zig",
133];
134
135#[cfg(test)]
136mod tests {
137    use super::*;
138
139    #[test]
140    fn test_from_extension_rust() {
141        assert_eq!(Language::from_extension("rs"), Language::Rust);
142    }
143
144    #[test]
145    fn test_from_extension_python() {
146        assert_eq!(Language::from_extension("py"), Language::Python);
147    }
148
149    #[test]
150    fn test_from_extension_unknown() {
151        assert_eq!(Language::from_extension("xyz"), Language::Unknown);
152    }
153
154    #[test]
155    fn test_extensions_rust() {
156        assert!(Language::Rust.extensions().contains(&"rs"));
157    }
158
159    #[test]
160    fn test_display_names() {
161        assert_eq!(Language::Rust.display_name(), "Rust");
162        assert_eq!(Language::Python.display_name(), "Python");
163        assert_eq!(Language::Unknown.display_name(), "Unknown");
164    }
165
166    #[test]
167    fn test_line_comments() {
168        assert_eq!(Language::Rust.line_comment(), "//");
169        assert_eq!(Language::Python.line_comment(), "#");
170    }
171
172    #[test]
173    fn test_tree_sitter_grammar_available() {
174        assert!(Language::Rust.has_tree_sitter_grammar());
175        assert!(Language::Python.has_tree_sitter_grammar());
176        assert!(!Language::Unknown.has_tree_sitter_grammar());
177    }
178}