use std::str::FromStr;
use strum::{Display, EnumString};
#[cfg(feature = "unic-langid")]
use unic_langid::{langid, LanguageIdentifier};
use crate::{
Chunk, Chunks, ChunksExt, ChunksRef, Spanned, Type, TypeError, TypeErrorKind,
};
macro_rules! languages {
($($id:ident ($doc:literal) => $val:literal $(| $alias:literal)*),*) => {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Display, EnumString)]
pub enum Language {
$(
#[doc = $doc]
#[strum(to_string = $doc, serialize = $val, $(serialize = $alias),*)]
$id
),*
}
impl Type for Language {
fn from_chunks(chunks: ChunksRef) -> Result<Self, TypeError> {
let span = chunks.span();
Self::from_str(&chunks.format_verbatim())
.map_err(|_| TypeError::new(span, TypeErrorKind::UnknownLangId))
}
fn to_chunks(&self) -> Chunks {
vec![Spanned::detached(Chunk::Verbatim(self.to_string()))]
}
}
};
}
languages! {
Basque ("Basque") => "basque",
Bulgarian ("Bulgarian") => "bulgarian",
Catalan ("Catalan") => "catalan",
Croatian ("Croatian") => "croatian",
Czech ("Czech") => "czech",
Danish ("Danish") => "danish",
Dutch ("Dutch") => "dutch",
EnglishUS ("American English") => "american" | "USenglish" | "english",
EnglishUK ("British English") => "british" | "UKenglish",
EnglishCA ("Canadian English") => "canadian",
EnglishAUS ("Australian English") => "australian",
EnglishNZ ("New Zealand English") => "newzealand",
Estonian ("Estonian") => "estonian",
Finnish ("Finnish") => "finnish",
French ("French") => "french",
German ("German") => "german",
GermanAT ("Austrian") => "austrian",
GermanCH ("Swiss German") => "swissgerman",
GermanNew ("New German") => "ngerman",
GermanATNew ("New Austrian") => "naustrian",
GermanCHNew ("New Swiss German") => "nswissgerman",
Greek ("Greek") => "greek",
Hungarian ("Hungarian") => "magyar" | "hungarian",
Icelandic ("Icelandic") => "icelandic",
Italian ("Italian") => "italian",
Latvian ("Latvian") => "latvian",
Lithuanian ("Lithuanian") => "lithuanian",
Marathi ("Marathi") => "marathi",
NorwegianBokmal ("Norwegian (Bokmål)") => "norsk",
NorwegainNynorsk ("Norwegian (Nynorsk)") => "nynorsk",
Polish ("Polish") => "polish",
PortugueseBR ("Brazilian Portuguese") => "brazil",
Portuguese ("Portuguese") => "portuguese" | "portuges",
Romanian ("Romanian") => "romanian",
Russian ("Russian") => "russian",
SerbianLatin ("Serbian (Latin)") => "serbian",
SerbianCyrillic ("Serbian (Cyrillic)") => "serbianc",
Slovak ("Slovak") => "slovak",
Slovene ("Slovene") => "slovene" | "slovenian",
Spanish ("Spanish") => "spanish",
Swedish ("Swedish") => "swedish",
Turkish ("Turkish") => "turkish",
Ukrainian ("Ukrainian") => "ukrainian"
}
#[cfg(feature = "unic-langid")]
impl From<Language> for LanguageIdentifier {
fn from(value: Language) -> Self {
match value {
Language::Basque => langid!("eu"),
Language::Bulgarian => langid!("bg"),
Language::Catalan => langid!("ca"),
Language::Croatian => langid!("hr"),
Language::Czech => langid!("cs"),
Language::Danish => langid!("da"),
Language::Dutch => langid!("nl"),
Language::EnglishUS => langid!("en-US"),
Language::EnglishUK => langid!("en-UK"),
Language::EnglishCA => langid!("en-CA"),
Language::EnglishAUS => langid!("en-AU"),
Language::EnglishNZ => langid!("en-NZ"),
Language::Estonian => langid!("et"),
Language::Finnish => langid!("fi"),
Language::French => langid!("fr"),
Language::German | Language::GermanNew => langid!("de"),
Language::GermanAT | Language::GermanATNew => langid!("de-AT"),
Language::GermanCH | Language::GermanCHNew => langid!("de-CH"),
Language::Greek => langid!("el"),
Language::Hungarian => langid!("hu"),
Language::Icelandic => langid!("is"),
Language::Italian => langid!("it"),
Language::Latvian => langid!("lv"),
Language::Lithuanian => langid!("lt"),
Language::Marathi => langid!("mr"),
Language::NorwegianBokmal => langid!("nb"),
Language::NorwegainNynorsk => langid!("nn"),
Language::Polish => langid!("pl"),
Language::PortugueseBR => langid!("pt-BR"),
Language::Portuguese => langid!("pt-PT"),
Language::Romanian => langid!("ro"),
Language::Russian => langid!("ru"),
Language::SerbianLatin => langid!("sr-Latn"),
Language::SerbianCyrillic => langid!("sr-Cyrl"),
Language::Slovak => langid!("sk"),
Language::Slovene => langid!("sl"),
Language::Spanish => langid!("es"),
Language::Swedish => langid!("sv"),
Language::Turkish => langid!("tr"),
Language::Ukrainian => langid!("uk"),
}
}
}
#[cfg(test)]
mod tests {
use crate::Language;
#[test]
fn aliases() {
assert_eq!(Language::EnglishUS, "english".parse().unwrap());
assert_eq!(Language::Portuguese, "portuges".parse().unwrap())
}
#[cfg(feature = "unic-langid")]
#[test]
fn langid() {
use unic_langid::LanguageIdentifier;
let lang: Language = "ngerman".parse().unwrap();
let id: LanguageIdentifier = lang.into();
assert_eq!("de", id.to_string());
}
}