use crate::language::Language;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct LanguageSet {
data: [Language; 8],
len: usize,
}
impl LanguageSet {
pub const fn new() -> Self {
Self {
data: [Language::Unknown; 8],
len: 0,
}
}
pub fn insert(&mut self, language: Language) {
if self.contains(language) || self.len >= self.data.len() {
return;
}
self.data[self.len] = language;
self.len += 1;
}
pub fn contains(&self, language: Language) -> bool {
self.data[..self.len].contains(&language)
}
pub fn as_slice(&self) -> &[Language] {
&self.data[..self.len]
}
}
impl Default for LanguageSet {
fn default() -> Self {
Self::new()
}
}
pub fn const_content_type_from_ext(ext: &str) -> &'static str {
match ext {
"html" | "htm" => "text/html",
"css" => "text/css",
"js" | "mjs" => "application/javascript",
"json" => "application/json",
"wasm" => "application/wasm",
"webp" => "image/webp",
"avif" => "image/avif",
_ => "application/octet-stream",
}
}
pub fn detect_language_fast(input: &str) -> Language {
if input.contains("fn ")
|| input.contains("impl ")
|| input.contains("let ")
{
return Language::Rust;
}
if input.contains("def ") || input.contains("import ") {
return Language::Python;
}
if input.contains("function ")
|| input.contains("const ")
|| input.contains("=>")
{
return Language::JavaScript;
}
if input.contains("package ") || input.contains("func ") {
return Language::Go;
}
Language::Unknown
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn set_is_stack_based_and_deduplicated() {
let mut set = LanguageSet::new();
set.insert(Language::Rust);
set.insert(Language::Rust);
set.insert(Language::Python);
assert_eq!(set.as_slice(), &[Language::Rust, Language::Python]);
}
#[test]
fn detects_const_content_types() {
assert_eq!(
const_content_type_from_ext("wasm"),
"application/wasm"
);
assert_eq!(
const_content_type_from_ext("unknown"),
"application/octet-stream"
);
}
#[test]
fn detects_fast_language_paths() {
assert_eq!(
detect_language_fast("fn main() {}"),
Language::Rust
);
assert_eq!(
detect_language_fast("def main(): pass"),
Language::Python
);
assert_eq!(
detect_language_fast("const x = () => 1;"),
Language::JavaScript
);
assert_eq!(
detect_language_fast("package main\nfunc main() {}"),
Language::Go
);
assert_eq!(
detect_language_fast("plain text"),
Language::Unknown
);
}
#[test]
fn set_capacity_is_bounded() {
let mut set = LanguageSet::new();
for _ in 0..16 {
set.insert(Language::Rust);
set.insert(Language::Python);
set.insert(Language::JavaScript);
set.insert(Language::Go);
set.insert(Language::Unknown);
}
assert!(set.as_slice().len() <= 8);
}
#[test]
fn default_matches_new_set() {
let via_default = LanguageSet::default();
let via_new = LanguageSet::new();
assert_eq!(via_default.as_slice(), via_new.as_slice());
}
}