Skip to main content

agentic_codebase/types/
language.rs

1//! Programming language detection and enumeration.
2
3use serde::{Deserialize, Serialize};
4use std::path::Path;
5
6/// Supported programming languages.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[repr(u8)]
9pub enum Language {
10    /// Python (.py, .pyi)
11    Python = 0,
12    /// Rust (.rs)
13    Rust = 1,
14    /// TypeScript (.ts, .tsx)
15    TypeScript = 2,
16    /// JavaScript (.js, .jsx, .mjs, .cjs)
17    JavaScript = 3,
18    /// Go (.go)
19    Go = 4,
20    /// C++ (.cpp, .cc, .cxx, .h, .hpp, .hxx)
21    Cpp = 5,
22    /// Unknown or unsupported language
23    Unknown = 255,
24}
25
26impl Language {
27    /// Convert from raw byte value.
28    pub fn from_u8(value: u8) -> Option<Self> {
29        match value {
30            0 => Some(Self::Python),
31            1 => Some(Self::Rust),
32            2 => Some(Self::TypeScript),
33            3 => Some(Self::JavaScript),
34            4 => Some(Self::Go),
35            5 => Some(Self::Cpp),
36            255 => Some(Self::Unknown),
37            _ => None,
38        }
39    }
40
41    /// Detect language from file extension.
42    pub fn from_extension(ext: &str) -> Self {
43        match ext.to_lowercase().as_str() {
44            "py" | "pyi" => Self::Python,
45            "rs" => Self::Rust,
46            "ts" | "tsx" => Self::TypeScript,
47            "js" | "jsx" | "mjs" | "cjs" => Self::JavaScript,
48            "go" => Self::Go,
49            "cpp" | "cc" | "cxx" | "c++" | "h" | "hpp" | "hxx" | "hh" => Self::Cpp,
50            _ => Self::Unknown,
51        }
52    }
53
54    /// Detect language from file path.
55    pub fn from_path(path: &Path) -> Self {
56        path.extension()
57            .and_then(|ext| ext.to_str())
58            .map(Self::from_extension)
59            .unwrap_or(Self::Unknown)
60    }
61
62    /// Returns the tree-sitter language for this enum variant.
63    pub fn tree_sitter_language(&self) -> Option<tree_sitter::Language> {
64        match self {
65            Self::Python => Some(tree_sitter_python::language()),
66            Self::Rust => Some(tree_sitter_rust::language()),
67            Self::TypeScript => Some(tree_sitter_typescript::language_typescript()),
68            Self::JavaScript => Some(tree_sitter_javascript::language()),
69            Self::Go => Some(tree_sitter_go::language()),
70            Self::Cpp => Some(tree_sitter_cpp::language()),
71            Self::Unknown => None,
72        }
73    }
74
75    /// Returns a human-readable name for the language.
76    pub fn name(&self) -> &'static str {
77        match self {
78            Self::Python => "Python",
79            Self::Rust => "Rust",
80            Self::TypeScript => "TypeScript",
81            Self::JavaScript => "JavaScript",
82            Self::Go => "Go",
83            Self::Cpp => "C++",
84            Self::Unknown => "Unknown",
85        }
86    }
87}
88
89impl std::fmt::Display for Language {
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91        write!(f, "{}", self.name())
92    }
93}