Files
WhispAssist/src-tauri/src/transcription/languages.rs
T

167 lines
4.6 KiB
Rust

//! Selectable transcription languages (T8.7, FR-TRX-4, M4.2) — the Settings
//! language dropdown shown when a multilingual model is active.
//!
//! ponytail: a fixed table, not a runtime query against whisper.cpp's
//! `whisper_lang_str`/`whisper_lang_max_id` — the ~100-language set whisper.cpp
//! ships is effectively static (OpenAI's Whisper `tokenizer.py` LANGUAGES
//! table), and hardcoding it here means the list is available to the UI even
//! before any model is loaded (no `cpu-transcription` feature dependency).
use crate::models::LanguageOption;
/// `(ISO-639-1 code, display label)`, exactly the codes whisper.cpp accepts
/// via `whisper_full_params.language`.
const LANGUAGES: &[(&str, &str)] = &[
("en", "English"),
("zh", "Chinese"),
("de", "German"),
("es", "Spanish"),
("ru", "Russian"),
("ko", "Korean"),
("fr", "French"),
("ja", "Japanese"),
("pt", "Portuguese"),
("tr", "Turkish"),
("pl", "Polish"),
("ca", "Catalan"),
("nl", "Dutch"),
("ar", "Arabic"),
("sv", "Swedish"),
("it", "Italian"),
("id", "Indonesian"),
("hi", "Hindi"),
("fi", "Finnish"),
("vi", "Vietnamese"),
("he", "Hebrew"),
("uk", "Ukrainian"),
("el", "Greek"),
("ms", "Malay"),
("cs", "Czech"),
("ro", "Romanian"),
("da", "Danish"),
("hu", "Hungarian"),
("ta", "Tamil"),
("no", "Norwegian"),
("th", "Thai"),
("ur", "Urdu"),
("hr", "Croatian"),
("bg", "Bulgarian"),
("lt", "Lithuanian"),
("la", "Latin"),
("mi", "Maori"),
("ml", "Malayalam"),
("cy", "Welsh"),
("sk", "Slovak"),
("te", "Telugu"),
("fa", "Persian"),
("lv", "Latvian"),
("bn", "Bengali"),
("sr", "Serbian"),
("az", "Azerbaijani"),
("sl", "Slovenian"),
("kn", "Kannada"),
("et", "Estonian"),
("mk", "Macedonian"),
("br", "Breton"),
("eu", "Basque"),
("is", "Icelandic"),
("hy", "Armenian"),
("ne", "Nepali"),
("mn", "Mongolian"),
("bs", "Bosnian"),
("kk", "Kazakh"),
("sq", "Albanian"),
("sw", "Swahili"),
("gl", "Galician"),
("mr", "Marathi"),
("pa", "Punjabi"),
("si", "Sinhala"),
("km", "Khmer"),
("sn", "Shona"),
("yo", "Yoruba"),
("so", "Somali"),
("af", "Afrikaans"),
("oc", "Occitan"),
("ka", "Georgian"),
("be", "Belarusian"),
("tg", "Tajik"),
("sd", "Sindhi"),
("gu", "Gujarati"),
("am", "Amharic"),
("yi", "Yiddish"),
("lo", "Lao"),
("uz", "Uzbek"),
("fo", "Faroese"),
("ht", "Haitian Creole"),
("ps", "Pashto"),
("tk", "Turkmen"),
("nn", "Nynorsk"),
("mt", "Maltese"),
("sa", "Sanskrit"),
("lb", "Luxembourgish"),
("my", "Myanmar"),
("bo", "Tibetan"),
("tl", "Tagalog"),
("mg", "Malagasy"),
("as", "Assamese"),
("tt", "Tatar"),
("haw", "Hawaiian"),
("ln", "Lingala"),
("ha", "Hausa"),
("ba", "Bashkir"),
("jw", "Javanese"),
("su", "Sundanese"),
("yue", "Cantonese"),
];
/// The dropdown's contents (`list_whisper_languages` command) — "Auto-detect"
/// itself is not in this list; the frontend prepends it (maps to `None`/no
/// `language` argument).
pub fn list() -> Vec<LanguageOption> {
LANGUAGES
.iter()
.map(|(code, label)| LanguageOption {
code: code.to_string(),
label: label.to_string(),
})
.collect()
}
/// Whether `code` is a known whisper.cpp language code (case-insensitive).
/// Used to validate an explicit selection before it's forced into
/// `FullParams::set_language` — an unrecognized code is still passed through
/// to whisper.cpp (it may support codes we haven't listed), but callers use
/// this to warn rather than silently accept a typo.
pub fn is_known(code: &str) -> bool {
LANGUAGES.iter().any(|(c, _)| c.eq_ignore_ascii_case(code))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn list_includes_english_and_common_languages() {
let langs = list();
assert!(langs.iter().any(|l| l.code == "en" && l.label == "English"));
assert!(langs.iter().any(|l| l.code == "es"));
assert!(langs.iter().any(|l| l.code == "fr"));
}
#[test]
fn codes_are_unique() {
let mut codes: Vec<&str> = LANGUAGES.iter().map(|(c, _)| *c).collect();
let before = codes.len();
codes.sort_unstable();
codes.dedup();
assert_eq!(before, codes.len(), "duplicate language code in catalog");
}
#[test]
fn is_known_is_case_insensitive() {
assert!(is_known("en"));
assert!(is_known("ES"));
assert!(!is_known("xx-not-a-real-code"));
}
}