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    /// Unknown or unsupported language
21    Unknown = 255,
22}
23
24impl Language {
25    /// Convert from raw byte value.
26    pub fn from_u8(value: u8) -> Option<Self> {
27        match value {
28            0 => Some(Self::Python),
29            1 => Some(Self::Rust),
30            2 => Some(Self::TypeScript),
31            3 => Some(Self::JavaScript),
32            4 => Some(Self::Go),
33            255 => Some(Self::Unknown),
34            _ => None,
35        }
36    }
37
38    /// Detect language from file extension.
39    pub fn from_extension(ext: &str) -> Self {
40        match ext.to_lowercase().as_str() {
41            "py" | "pyi" => Self::Python,
42            "rs" => Self::Rust,
43            "ts" | "tsx" => Self::TypeScript,
44            "js" | "jsx" | "mjs" | "cjs" => Self::JavaScript,
45            "go" => Self::Go,
46            _ => Self::Unknown,
47        }
48    }
49
50    /// Detect language from file path.
51    pub fn from_path(path: &Path) -> Self {
52        path.extension()
53            .and_then(|ext| ext.to_str())
54            .map(Self::from_extension)
55            .unwrap_or(Self::Unknown)
56    }
57
58    /// Returns the tree-sitter language for this enum variant.
59    pub fn tree_sitter_language(&self) -> Option<tree_sitter::Language> {
60        match self {
61            Self::Python => Some(tree_sitter_python::language()),
62            Self::Rust => Some(tree_sitter_rust::language()),
63            Self::TypeScript => Some(tree_sitter_typescript::language_typescript()),
64            Self::JavaScript => Some(tree_sitter_javascript::language()),
65            Self::Go => Some(tree_sitter_go::language()),
66            Self::Unknown => None,
67        }
68    }
69
70    /// Returns a human-readable name for the language.
71    pub fn name(&self) -> &'static str {
72        match self {
73            Self::Python => "Python",
74            Self::Rust => "Rust",
75            Self::TypeScript => "TypeScript",
76            Self::JavaScript => "JavaScript",
77            Self::Go => "Go",
78            Self::Unknown => "Unknown",
79        }
80    }
81}
82
83impl std::fmt::Display for Language {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        write!(f, "{}", self.name())
86    }
87}