Skip to main content

code_analyze_mcp/
lang.rs

1//! Language detection by file extension.
2//!
3//! Maps file extensions to supported language identifiers.
4
5const EXTENSION_MAP: &[(&str, &str)] = &[
6    #[cfg(feature = "lang-fortran")]
7    ("f", "fortran"),
8    #[cfg(feature = "lang-fortran")]
9    ("f03", "fortran"),
10    #[cfg(feature = "lang-fortran")]
11    ("f08", "fortran"),
12    #[cfg(feature = "lang-fortran")]
13    ("f77", "fortran"),
14    #[cfg(feature = "lang-fortran")]
15    ("f90", "fortran"),
16    #[cfg(feature = "lang-fortran")]
17    ("f95", "fortran"),
18    #[cfg(feature = "lang-fortran")]
19    ("for", "fortran"),
20    #[cfg(feature = "lang-fortran")]
21    ("ftn", "fortran"),
22    #[cfg(feature = "lang-go")]
23    ("go", "go"),
24    #[cfg(feature = "lang-java")]
25    ("java", "java"),
26    #[cfg(feature = "lang-python")]
27    ("py", "python"),
28    #[cfg(feature = "lang-rust")]
29    ("rs", "rust"),
30    #[cfg(feature = "lang-typescript")]
31    ("ts", "typescript"),
32    #[cfg(feature = "lang-tsx")]
33    ("tsx", "tsx"),
34];
35
36/// Returns the language identifier for the given file extension, or `None` if unsupported.
37///
38/// The lookup is case-insensitive. Supported extensions include `rs`, `py`, `go`, `java`,
39/// `ts`, `tsx`, `f90`, `f95`, `for`, `ftn`, and other Fortran variants.
40#[must_use]
41pub fn language_from_extension(ext: &str) -> Option<&'static str> {
42    EXTENSION_MAP
43        .iter()
44        .find(|(e, _)| e.eq_ignore_ascii_case(ext))
45        .map(|(_, lang)| *lang)
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_language_from_extension_happy_path() {
54        #[cfg(feature = "lang-rust")]
55        assert_eq!(language_from_extension("rs"), Some("rust"));
56        #[cfg(feature = "lang-python")]
57        assert_eq!(language_from_extension("py"), Some("python"));
58        #[cfg(feature = "lang-go")]
59        assert_eq!(language_from_extension("go"), Some("go"));
60        #[cfg(feature = "lang-java")]
61        assert_eq!(language_from_extension("java"), Some("java"));
62        #[cfg(feature = "lang-typescript")]
63        assert_eq!(language_from_extension("ts"), Some("typescript"));
64        #[cfg(feature = "lang-tsx")]
65        assert_eq!(language_from_extension("tsx"), Some("tsx"));
66        #[cfg(feature = "lang-fortran")]
67        assert_eq!(language_from_extension("f90"), Some("fortran"));
68        #[cfg(feature = "lang-fortran")]
69        assert_eq!(language_from_extension("for"), Some("fortran"));
70        #[cfg(feature = "lang-fortran")]
71        assert_eq!(language_from_extension("ftn"), Some("fortran"));
72    }
73
74    #[test]
75    fn test_language_from_extension_edge_case() {
76        assert_eq!(language_from_extension("unknown"), None);
77        assert_eq!(language_from_extension(""), None);
78        #[cfg(feature = "lang-rust")]
79        assert_eq!(language_from_extension("RS"), Some("rust"));
80        // Uppercase Fortran extensions resolved via eq_ignore_ascii_case
81        #[cfg(feature = "lang-fortran")]
82        assert_eq!(language_from_extension("F90"), Some("fortran"));
83        #[cfg(feature = "lang-fortran")]
84        assert_eq!(language_from_extension("FOR"), Some("fortran"));
85    }
86}