use std::path::Path;
use crate::LanguageId;
use crate::registry;
#[must_use]
pub fn language_id_from_path(path: &Path) -> Option<LanguageId> {
let ext = extension(path)?;
registry::all()
.iter()
.find(|g| g.extensions.contains(&ext.as_str()))
.map(|g| g.id)
}
#[must_use]
pub fn language_name_from_path(path: &Path) -> Option<&'static str> {
if let Some(ext) = extension(path)
&& let Some(g) = registry::all()
.iter()
.find(|g| g.extensions.contains(&ext.as_str()))
{
return Some(g.name);
}
let ft = karet_filetype::file_type_for_path(path);
ft.is_recognized().then_some(ft.name())
}
#[must_use]
pub fn language_id_from_injection_name(name: &str) -> Option<LanguageId> {
let name = name.trim().to_ascii_lowercase();
registry::all()
.iter()
.find(|g| g.names.contains(&name.as_str()))
.map(|g| g.id)
}
fn extension(path: &Path) -> Option<String> {
path.extension()?.to_str().map(str::to_ascii_lowercase)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unknown_extension_is_unlabelled() {
let p = Path::new("file.unknownext");
assert_eq!(language_id_from_path(p), None);
assert_eq!(language_name_from_path(p), None);
}
#[test]
fn non_compiled_language_still_named() {
let p = Path::new("Main.kt");
assert_eq!(language_id_from_path(p), None);
assert_eq!(language_name_from_path(p), Some("Kotlin"));
}
#[test]
fn injection_names_are_case_insensitive_with_aliases() {
if let Some(rust) = language_id_from_injection_name("rust") {
assert_eq!(language_id_from_injection_name("rs"), Some(rust));
assert_eq!(language_id_from_injection_name(" RuSt "), Some(rust));
}
}
#[test]
fn unknown_injection_name_is_none() {
assert_eq!(language_id_from_injection_name("jsdoc"), None);
assert_eq!(language_id_from_injection_name("regex"), None);
assert_eq!(language_id_from_injection_name(""), None);
}
#[cfg(feature = "lang-markdown")]
#[test]
fn inline_markdown_is_reachable_by_name_but_never_by_path() {
assert!(language_id_from_injection_name("markdown_inline").is_some());
assert_ne!(
language_id_from_path(Path::new("x.md")),
language_id_from_injection_name("markdown_inline")
);
}
#[test]
fn extension_is_case_insensitive() {
assert_eq!(extension(Path::new("X.MD")).as_deref(), Some("md"));
assert_eq!(
language_name_from_path(Path::new("README.MD")),
Some("Markdown")
);
}
}