#![cfg_attr(coverage_nightly, coverage(off))]
#[cfg(feature = "shell-ast")]
pub mod bash;
#[cfg(feature = "csharp-ast")]
pub mod csharp;
#[cfg(feature = "go-ast")]
pub mod go;
#[cfg(feature = "java-ast")]
pub mod java;
pub mod javascript;
#[cfg(feature = "kotlin-ast")]
pub mod kotlin;
#[cfg(feature = "lean-ast")]
pub mod lean;
#[cfg(feature = "php-ast")]
pub mod php;
#[cfg(feature = "ruchy-ast")]
pub mod ruchy;
#[cfg(feature = "ruchy-ast")]
pub mod ruchy_ml;
#[cfg(feature = "scala-ast")]
pub mod scala;
#[cfg(feature = "swift-ast")]
pub mod swift;
pub mod typescript;
#[cfg(feature = "wasm-ast")]
pub mod wasm;
use std::path::Path;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Language {
Rust,
Ruchy,
Python,
JavaScript,
TypeScript,
Go,
Java,
Kotlin,
CSharp,
Cpp,
Lean,
Unknown,
}
impl Language {
#[must_use]
pub fn from_extension(path: &Path) -> Self {
path.extension()
.and_then(|ext| ext.to_str())
.map_or(Language::Unknown, |ext| match ext.to_lowercase().as_str() {
"rs" => Language::Rust,
"ruchy" | "rh" => Language::Ruchy,
"py" => Language::Python,
"js" | "mjs" => Language::JavaScript,
"ts" | "tsx" => Language::TypeScript,
"go" => Language::Go,
"java" => Language::Java,
"kt" | "kts" => Language::Kotlin,
"cs" => Language::CSharp,
"cpp" | "cc" | "cxx" | "c++" | "cu" | "cuh" => Language::Cpp,
"c" => Language::Cpp,
"lean" => Language::Lean,
_ => Language::Unknown,
})
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Language::Rust => "Rust",
Language::Ruchy => "Ruchy",
Language::Python => "Python",
Language::JavaScript => "JavaScript",
Language::TypeScript => "TypeScript",
Language::Go => "Go",
Language::Java => "Java",
Language::Kotlin => "Kotlin",
Language::CSharp => "C#",
Language::Cpp => "C++",
Language::Lean => "Lean",
Language::Unknown => "Unknown",
}
}
#[must_use]
pub fn extensions(&self) -> &'static [&'static str] {
match self {
Language::Rust => &["rs"],
Language::Ruchy => &["ruchy", "rh"],
Language::Python => &["py", "pyw"],
Language::JavaScript => &["js", "mjs", "cjs"],
Language::TypeScript => &["ts", "tsx"],
Language::Go => &["go"],
Language::Java => &["java"],
Language::Kotlin => &["kt", "kts"],
Language::CSharp => &["cs"],
Language::Cpp => &["cpp", "cc", "cxx", "c++", "c"],
Language::Lean => &["lean"],
Language::Unknown => &[],
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn test_language_detection() {
assert_eq!(
Language::from_extension(&PathBuf::from("test.rs")),
Language::Rust
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.ruchy")),
Language::Ruchy
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.rh")),
Language::Ruchy
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.py")),
Language::Python
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.js")),
Language::JavaScript
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.ts")),
Language::TypeScript
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.go")),
Language::Go
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.java")),
Language::Java
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.kt")),
Language::Kotlin
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.cs")),
Language::CSharp
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.lean")),
Language::Lean
);
assert_eq!(
Language::from_extension(&PathBuf::from("test.unknown")),
Language::Unknown
);
}
#[test]
fn test_language_names() {
assert_eq!(Language::Ruchy.name(), "Ruchy");
assert_eq!(Language::Rust.name(), "Rust");
assert_eq!(Language::Python.name(), "Python");
assert_eq!(Language::Java.name(), "Java");
assert_eq!(Language::Kotlin.name(), "Kotlin");
assert_eq!(Language::CSharp.name(), "C#");
}
#[test]
fn test_language_extensions() {
assert!(Language::Ruchy.extensions().contains(&"ruchy"));
assert!(Language::Ruchy.extensions().contains(&"rh"));
assert!(Language::Rust.extensions().contains(&"rs"));
assert!(Language::Python.extensions().contains(&"py"));
assert!(Language::Java.extensions().contains(&"java"));
assert!(Language::Kotlin.extensions().contains(&"kt"));
assert!(Language::Kotlin.extensions().contains(&"kts"));
assert!(Language::CSharp.extensions().contains(&"cs"));
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}