use std::path::Path;
use serde::{Deserialize, Serialize};
pub(crate) mod go;
pub(crate) mod java;
pub(crate) mod javascript;
pub(crate) mod kotlin;
pub(crate) mod python;
pub(crate) mod rust;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Language {
Go,
Java,
Kotlin,
Python,
JavaScript,
TypeScript,
TypeScriptReact,
Rust,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Ecosystem {
Go,
Java,
Python,
JavaScript,
Rust,
}
pub(crate) fn language_for_path(path: &Path) -> Option<Language> {
let ext = path.extension().and_then(|ext| ext.to_str())?;
if go::EXTENSIONS.contains(&ext) {
return Some(Language::Go);
}
if java::EXTENSIONS.contains(&ext) {
return Some(Language::Java);
}
if kotlin::EXTENSIONS.contains(&ext) {
return Some(Language::Kotlin);
}
if python::EXTENSIONS.contains(&ext) {
return Some(Language::Python);
}
if javascript::EXTENSIONS.contains(&ext) {
return Some(Language::JavaScript);
}
if javascript::TYPESCRIPT_EXTENSIONS.contains(&ext) {
return Some(Language::TypeScript);
}
if javascript::TSX_EXTENSIONS.contains(&ext) {
return Some(Language::TypeScriptReact);
}
if rust::EXTENSIONS.contains(&ext) {
return Some(Language::Rust);
}
None
}
pub(crate) fn ecosystem_for_language(language: Language) -> Ecosystem {
match language {
Language::Go => Ecosystem::Go,
Language::Java | Language::Kotlin => Ecosystem::Java,
Language::Python => Ecosystem::Python,
Language::JavaScript | Language::TypeScript | Language::TypeScriptReact => {
Ecosystem::JavaScript
}
Language::Rust => Ecosystem::Rust,
}
}
pub(crate) fn tree_sitter_language(language: Language) -> tree_sitter::Language {
match language {
Language::Go => go::language(),
Language::Java => java::language(),
Language::Kotlin => kotlin::language(),
Language::Python => python::language(),
Language::JavaScript => javascript::language(),
Language::TypeScript => javascript::language_typescript(),
Language::TypeScriptReact => javascript::language_tsx(),
Language::Rust => rust::language(),
}
}
#[cfg(test)]
mod tests {
use super::{Language, language_for_path};
use std::path::PathBuf;
#[test]
fn recognizes_python_extension() {
let lang = language_for_path(&PathBuf::from("file.py"));
assert_eq!(lang, Some(Language::Python));
}
#[test]
fn recognizes_javascript_extension() {
let lang = language_for_path(&PathBuf::from("file.js"));
assert_eq!(lang, Some(Language::JavaScript));
}
#[test]
fn recognizes_jsx_extension() {
let lang = language_for_path(&PathBuf::from("file.jsx"));
assert_eq!(lang, Some(Language::JavaScript));
}
#[test]
fn recognizes_typescript_extension() {
let lang = language_for_path(&PathBuf::from("file.ts"));
assert_eq!(lang, Some(Language::TypeScript));
}
#[test]
fn recognizes_tsx_extension() {
let lang = language_for_path(&PathBuf::from("file.tsx"));
assert_eq!(lang, Some(Language::TypeScriptReact));
}
#[test]
fn recognizes_rust_extension() {
let lang = language_for_path(&PathBuf::from("file.rs"));
assert_eq!(lang, Some(Language::Rust));
}
#[test]
fn recognizes_java_extension() {
let lang = language_for_path(&PathBuf::from("file.java"));
assert_eq!(lang, Some(Language::Java));
}
#[test]
fn recognizes_kotlin_extension() {
let lang = language_for_path(&PathBuf::from("file.kt"));
assert_eq!(lang, Some(Language::Kotlin));
}
#[test]
fn recognizes_kotlin_script_extension() {
let lang = language_for_path(&PathBuf::from("file.kts"));
assert_eq!(lang, Some(Language::Kotlin));
}
#[test]
fn recognizes_go_extension() {
let lang = language_for_path(&PathBuf::from("file.go"));
assert_eq!(lang, Some(Language::Go));
}
#[test]
fn ignores_unknown_extensions() {
let lang = language_for_path(&PathBuf::from("file.txt"));
assert_eq!(lang, None);
}
}