Skip to main content

code_analyze_core/
lang.rs

1// SPDX-FileCopyrightText: 2026 code-analyze-mcp contributors
2// SPDX-License-Identifier: Apache-2.0
3//! Language detection by file extension.
4//!
5//! Maps file extensions to supported language identifiers.
6
7const EXTENSION_MAP: &[(&str, &str)] = &[
8    #[cfg(feature = "lang-fortran")]
9    ("f", "fortran"),
10    #[cfg(feature = "lang-fortran")]
11    ("f03", "fortran"),
12    #[cfg(feature = "lang-fortran")]
13    ("f08", "fortran"),
14    #[cfg(feature = "lang-fortran")]
15    ("f77", "fortran"),
16    #[cfg(feature = "lang-fortran")]
17    ("f90", "fortran"),
18    #[cfg(feature = "lang-fortran")]
19    ("f95", "fortran"),
20    #[cfg(feature = "lang-fortran")]
21    ("for", "fortran"),
22    #[cfg(feature = "lang-fortran")]
23    ("ftn", "fortran"),
24    #[cfg(feature = "lang-go")]
25    ("go", "go"),
26    #[cfg(feature = "lang-java")]
27    ("java", "java"),
28    #[cfg(feature = "lang-python")]
29    ("py", "python"),
30    #[cfg(feature = "lang-rust")]
31    ("rs", "rust"),
32    #[cfg(feature = "lang-typescript")]
33    ("ts", "typescript"),
34    #[cfg(feature = "lang-tsx")]
35    ("tsx", "tsx"),
36];
37
38/// Returns the language identifier for the given file extension, or `None` if unsupported.
39///
40/// The lookup is case-insensitive. Supported extensions include `rs`, `py`, `go`, `java`,
41/// `ts`, `tsx`, `f90`, `f95`, `for`, `ftn`, and other Fortran variants.
42#[must_use]
43pub fn language_for_extension(ext: &str) -> Option<&'static str> {
44    EXTENSION_MAP
45        .iter()
46        .find(|(e, _)| e.eq_ignore_ascii_case(ext))
47        .map(|(_, lang)| *lang)
48}
49
50/// Returns a static slice of all supported language names based on compiled features.
51///
52/// The returned slice contains language identifiers like `"rust"`, `"python"`, `"go"`, etc.,
53/// depending on which language features are enabled at compile time.
54#[must_use]
55pub fn supported_languages() -> &'static [&'static str] {
56    &[
57        #[cfg(feature = "lang-rust")]
58        "rust",
59        #[cfg(feature = "lang-go")]
60        "go",
61        #[cfg(feature = "lang-java")]
62        "java",
63        #[cfg(feature = "lang-python")]
64        "python",
65        #[cfg(feature = "lang-typescript")]
66        "typescript",
67        #[cfg(feature = "lang-tsx")]
68        "tsx",
69        #[cfg(feature = "lang-fortran")]
70        "fortran",
71    ]
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_language_for_extension_happy_path() {
80        #[cfg(feature = "lang-rust")]
81        assert_eq!(language_for_extension("rs"), Some("rust"));
82        #[cfg(feature = "lang-python")]
83        assert_eq!(language_for_extension("py"), Some("python"));
84        #[cfg(feature = "lang-go")]
85        assert_eq!(language_for_extension("go"), Some("go"));
86        #[cfg(feature = "lang-java")]
87        assert_eq!(language_for_extension("java"), Some("java"));
88        #[cfg(feature = "lang-typescript")]
89        assert_eq!(language_for_extension("ts"), Some("typescript"));
90        #[cfg(feature = "lang-tsx")]
91        assert_eq!(language_for_extension("tsx"), Some("tsx"));
92        #[cfg(feature = "lang-fortran")]
93        assert_eq!(language_for_extension("f90"), Some("fortran"));
94        #[cfg(feature = "lang-fortran")]
95        assert_eq!(language_for_extension("for"), Some("fortran"));
96        #[cfg(feature = "lang-fortran")]
97        assert_eq!(language_for_extension("ftn"), Some("fortran"));
98    }
99
100    #[test]
101    fn test_language_for_extension_edge_case() {
102        assert_eq!(language_for_extension("unknown"), None);
103        assert_eq!(language_for_extension(""), None);
104        #[cfg(feature = "lang-rust")]
105        assert_eq!(language_for_extension("RS"), Some("rust"));
106        // Uppercase Fortran extensions resolved via eq_ignore_ascii_case
107        #[cfg(feature = "lang-fortran")]
108        assert_eq!(language_for_extension("F90"), Some("fortran"));
109        #[cfg(feature = "lang-fortran")]
110        assert_eq!(language_for_extension("FOR"), Some("fortran"));
111    }
112}