use std::fmt;
use std::str::FromStr;
use crate::error::Error;
#[cfg(feature = "enum-map")]
use enum_map::Enum;
#[cfg_attr(feature = "enum-map", derive(Enum))]
#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
pub enum Lang {
Epo = 0,
Eng = 1,
Rus = 2,
Cmn = 3,
Spa = 4,
Por = 5,
Ita = 6,
Ben = 7,
Fra = 8,
Deu = 9,
Ukr = 10,
Kat = 11,
Ara = 12,
Hin = 13,
Jpn = 14,
Heb = 15,
Yid = 16,
Pol = 17,
Amh = 18,
Jav = 19,
Kor = 20,
Nob = 21,
Dan = 22,
Swe = 23,
Fin = 24,
Tur = 25,
Nld = 26,
Hun = 27,
Ces = 28,
Ell = 29,
Bul = 30,
Bel = 31,
Mar = 32,
Kan = 33,
Ron = 34,
Slv = 35,
Hrv = 36,
Srp = 37,
Mkd = 38,
Lit = 39,
Lav = 40,
Est = 41,
Tam = 42,
Vie = 43,
Urd = 44,
Tha = 45,
Guj = 46,
Uzb = 47,
Pan = 48,
Aze = 49,
Ind = 50,
Tel = 51,
Pes = 52,
Mal = 53,
Ori = 54,
Mya = 55,
Nep = 56,
Sin = 57,
Khm = 58,
Tuk = 59,
Aka = 60,
Zul = 61,
Sna = 62,
Afr = 63,
Lat = 64,
Slk = 65,
Cat = 66,
}
const VALUES: [Lang; 67] = [
Lang::Epo,
Lang::Eng,
Lang::Rus,
Lang::Cmn,
Lang::Spa,
Lang::Por,
Lang::Ita,
Lang::Ben,
Lang::Fra,
Lang::Deu,
Lang::Ukr,
Lang::Kat,
Lang::Ara,
Lang::Hin,
Lang::Jpn,
Lang::Heb,
Lang::Yid,
Lang::Pol,
Lang::Amh,
Lang::Jav,
Lang::Kor,
Lang::Nob,
Lang::Dan,
Lang::Swe,
Lang::Fin,
Lang::Tur,
Lang::Nld,
Lang::Hun,
Lang::Ces,
Lang::Ell,
Lang::Bul,
Lang::Bel,
Lang::Mar,
Lang::Kan,
Lang::Ron,
Lang::Slv,
Lang::Hrv,
Lang::Srp,
Lang::Mkd,
Lang::Lit,
Lang::Lav,
Lang::Est,
Lang::Tam,
Lang::Vie,
Lang::Urd,
Lang::Tha,
Lang::Guj,
Lang::Uzb,
Lang::Pan,
Lang::Aze,
Lang::Ind,
Lang::Tel,
Lang::Pes,
Lang::Mal,
Lang::Ori,
Lang::Mya,
Lang::Nep,
Lang::Sin,
Lang::Khm,
Lang::Tuk,
Lang::Aka,
Lang::Zul,
Lang::Sna,
Lang::Afr,
Lang::Lat,
Lang::Slk,
Lang::Cat,
];
fn lang_from_code<S: Into<String>>(code: S) -> Option<Lang> {
match code.into().to_lowercase().as_ref() {
"epo" => Some(Lang::Epo),
"eng" => Some(Lang::Eng),
"rus" => Some(Lang::Rus),
"cmn" => Some(Lang::Cmn),
"spa" => Some(Lang::Spa),
"por" => Some(Lang::Por),
"ita" => Some(Lang::Ita),
"ben" => Some(Lang::Ben),
"fra" => Some(Lang::Fra),
"deu" => Some(Lang::Deu),
"ukr" => Some(Lang::Ukr),
"kat" => Some(Lang::Kat),
"ara" => Some(Lang::Ara),
"hin" => Some(Lang::Hin),
"jpn" => Some(Lang::Jpn),
"heb" => Some(Lang::Heb),
"yid" => Some(Lang::Yid),
"pol" => Some(Lang::Pol),
"amh" => Some(Lang::Amh),
"jav" => Some(Lang::Jav),
"kor" => Some(Lang::Kor),
"nob" => Some(Lang::Nob),
"dan" => Some(Lang::Dan),
"swe" => Some(Lang::Swe),
"fin" => Some(Lang::Fin),
"tur" => Some(Lang::Tur),
"nld" => Some(Lang::Nld),
"hun" => Some(Lang::Hun),
"ces" => Some(Lang::Ces),
"ell" => Some(Lang::Ell),
"bul" => Some(Lang::Bul),
"bel" => Some(Lang::Bel),
"mar" => Some(Lang::Mar),
"kan" => Some(Lang::Kan),
"ron" => Some(Lang::Ron),
"slv" => Some(Lang::Slv),
"hrv" => Some(Lang::Hrv),
"srp" => Some(Lang::Srp),
"mkd" => Some(Lang::Mkd),
"lit" => Some(Lang::Lit),
"lav" => Some(Lang::Lav),
"est" => Some(Lang::Est),
"tam" => Some(Lang::Tam),
"vie" => Some(Lang::Vie),
"urd" => Some(Lang::Urd),
"tha" => Some(Lang::Tha),
"guj" => Some(Lang::Guj),
"uzb" => Some(Lang::Uzb),
"pan" => Some(Lang::Pan),
"aze" => Some(Lang::Aze),
"ind" => Some(Lang::Ind),
"tel" => Some(Lang::Tel),
"pes" => Some(Lang::Pes),
"mal" => Some(Lang::Mal),
"ori" => Some(Lang::Ori),
"mya" => Some(Lang::Mya),
"nep" => Some(Lang::Nep),
"sin" => Some(Lang::Sin),
"khm" => Some(Lang::Khm),
"tuk" => Some(Lang::Tuk),
"aka" => Some(Lang::Aka),
"zul" => Some(Lang::Zul),
"sna" => Some(Lang::Sna),
"afr" => Some(Lang::Afr),
"lat" => Some(Lang::Lat),
"slk" => Some(Lang::Slk),
"cat" => Some(Lang::Cat),
_ => None,
}
}
fn lang_to_code(lang: Lang) -> &'static str {
match lang {
Lang::Epo => "epo",
Lang::Eng => "eng",
Lang::Rus => "rus",
Lang::Cmn => "cmn",
Lang::Spa => "spa",
Lang::Por => "por",
Lang::Ita => "ita",
Lang::Ben => "ben",
Lang::Fra => "fra",
Lang::Deu => "deu",
Lang::Ukr => "ukr",
Lang::Kat => "kat",
Lang::Ara => "ara",
Lang::Hin => "hin",
Lang::Jpn => "jpn",
Lang::Heb => "heb",
Lang::Yid => "yid",
Lang::Pol => "pol",
Lang::Amh => "amh",
Lang::Jav => "jav",
Lang::Kor => "kor",
Lang::Nob => "nob",
Lang::Dan => "dan",
Lang::Swe => "swe",
Lang::Fin => "fin",
Lang::Tur => "tur",
Lang::Nld => "nld",
Lang::Hun => "hun",
Lang::Ces => "ces",
Lang::Ell => "ell",
Lang::Bul => "bul",
Lang::Bel => "bel",
Lang::Mar => "mar",
Lang::Kan => "kan",
Lang::Ron => "ron",
Lang::Slv => "slv",
Lang::Hrv => "hrv",
Lang::Srp => "srp",
Lang::Mkd => "mkd",
Lang::Lit => "lit",
Lang::Lav => "lav",
Lang::Est => "est",
Lang::Tam => "tam",
Lang::Vie => "vie",
Lang::Urd => "urd",
Lang::Tha => "tha",
Lang::Guj => "guj",
Lang::Uzb => "uzb",
Lang::Pan => "pan",
Lang::Aze => "aze",
Lang::Ind => "ind",
Lang::Tel => "tel",
Lang::Pes => "pes",
Lang::Mal => "mal",
Lang::Ori => "ori",
Lang::Mya => "mya",
Lang::Nep => "nep",
Lang::Sin => "sin",
Lang::Khm => "khm",
Lang::Tuk => "tuk",
Lang::Aka => "aka",
Lang::Zul => "zul",
Lang::Sna => "sna",
Lang::Afr => "afr",
Lang::Lat => "lat",
Lang::Slk => "slk",
Lang::Cat => "cat",
}
}
fn lang_to_name(lang: Lang) -> &'static str {
match lang {
Lang::Epo => "Esperanto",
Lang::Eng => "English",
Lang::Rus => "Русский",
Lang::Cmn => "普通话",
Lang::Spa => "Español",
Lang::Por => "Português",
Lang::Ita => "Italiano",
Lang::Ben => "বাংলা",
Lang::Fra => "Français",
Lang::Deu => "Deutsch",
Lang::Ukr => "Українська",
Lang::Kat => "ქართული",
Lang::Ara => "العربية",
Lang::Hin => "हिन्दी",
Lang::Jpn => "日本語",
Lang::Heb => "עברית",
Lang::Yid => "ייִדיש",
Lang::Pol => "Polski",
Lang::Amh => "አማርኛ",
Lang::Jav => "Basa Jawa",
Lang::Kor => "한국어",
Lang::Nob => "Bokmål",
Lang::Dan => "Dansk",
Lang::Swe => "Svenska",
Lang::Fin => "Suomi",
Lang::Tur => "Türkçe",
Lang::Nld => "Nederlands",
Lang::Hun => "Magyar",
Lang::Ces => "Čeština",
Lang::Ell => "Ελληνικά",
Lang::Bul => "Български",
Lang::Bel => "Беларуская",
Lang::Mar => "मराठी",
Lang::Kan => "ಕನ್ನಡ",
Lang::Ron => "Română",
Lang::Slv => "Slovenščina",
Lang::Hrv => "Hrvatski",
Lang::Srp => "Српски",
Lang::Mkd => "Македонски",
Lang::Lit => "Lietuvių",
Lang::Lav => "Latviešu",
Lang::Est => "Eesti",
Lang::Tam => "தமிழ்",
Lang::Vie => "Tiếng Việt",
Lang::Urd => "اُردُو",
Lang::Tha => "ภาษาไทย",
Lang::Guj => "ગુજરાતી",
Lang::Uzb => "Oʻzbekcha",
Lang::Pan => "ਪੰਜਾਬੀ",
Lang::Aze => "Azərbaycanca",
Lang::Ind => "Bahasa Indonesia",
Lang::Tel => "తెలుగు",
Lang::Pes => "فارسی",
Lang::Mal => "മലയാളം",
Lang::Ori => "ଓଡ଼ିଆ",
Lang::Mya => "မြန်မာစာ",
Lang::Nep => "नेपाली",
Lang::Sin => "සිංහල",
Lang::Khm => "ភាសាខ្មែរ",
Lang::Tuk => "Türkmençe",
Lang::Aka => "Akan",
Lang::Zul => "IsiZulu",
Lang::Sna => "ChiShona",
Lang::Afr => "Afrikaans",
Lang::Lat => "Lingua Latina",
Lang::Slk => "Slovenčina",
Lang::Cat => "Català",
}
}
fn lang_to_eng_name(lang: Lang) -> &'static str {
match lang {
Lang::Epo => "Esperanto",
Lang::Eng => "English",
Lang::Rus => "Russian",
Lang::Cmn => "Mandarin",
Lang::Spa => "Spanish",
Lang::Por => "Portuguese",
Lang::Ita => "Italian",
Lang::Ben => "Bengali",
Lang::Fra => "French",
Lang::Deu => "German",
Lang::Ukr => "Ukrainian",
Lang::Kat => "Georgian",
Lang::Ara => "Arabic",
Lang::Hin => "Hindi",
Lang::Jpn => "Japanese",
Lang::Heb => "Hebrew",
Lang::Yid => "Yiddish",
Lang::Pol => "Polish",
Lang::Amh => "Amharic",
Lang::Jav => "Javanese",
Lang::Kor => "Korean",
Lang::Nob => "Bokmal",
Lang::Dan => "Danish",
Lang::Swe => "Swedish",
Lang::Fin => "Finnish",
Lang::Tur => "Turkish",
Lang::Nld => "Dutch",
Lang::Hun => "Hungarian",
Lang::Ces => "Czech",
Lang::Ell => "Greek",
Lang::Bul => "Bulgarian",
Lang::Bel => "Belarusian",
Lang::Mar => "Marathi",
Lang::Kan => "Kannada",
Lang::Ron => "Romanian",
Lang::Slv => "Slovene",
Lang::Hrv => "Croatian",
Lang::Srp => "Serbian",
Lang::Mkd => "Macedonian",
Lang::Lit => "Lithuanian",
Lang::Lav => "Latvian",
Lang::Est => "Estonian",
Lang::Tam => "Tamil",
Lang::Vie => "Vietnamese",
Lang::Urd => "Urdu",
Lang::Tha => "Thai",
Lang::Guj => "Gujarati",
Lang::Uzb => "Uzbek",
Lang::Pan => "Punjabi",
Lang::Aze => "Azerbaijani",
Lang::Ind => "Indonesian",
Lang::Tel => "Telugu",
Lang::Pes => "Persian",
Lang::Mal => "Malayalam",
Lang::Ori => "Oriya",
Lang::Mya => "Burmese",
Lang::Nep => "Nepali",
Lang::Sin => "Sinhalese",
Lang::Khm => "Khmer",
Lang::Tuk => "Turkmen",
Lang::Aka => "Akan",
Lang::Zul => "Zulu",
Lang::Sna => "Shona",
Lang::Afr => "Afrikaans",
Lang::Lat => "Latin",
Lang::Slk => "Slovak",
Lang::Cat => "Catalan",
}
}
impl Lang {
pub fn from_code<S: Into<String>>(code: S) -> Option<Lang> {
lang_from_code(code)
}
pub fn code(&self) -> &'static str {
lang_to_code(*self)
}
pub fn name(self) -> &'static str {
lang_to_name(self)
}
pub fn eng_name(self) -> &'static str {
lang_to_eng_name(self)
}
pub fn all() -> &'static [Lang] {
&VALUES
}
}
impl fmt::Display for Lang {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name())
}
}
impl FromStr for Lang {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Lang::from_code(s).ok_or_else(|| Error::ParseLang(s.to_string()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_code() {
assert_eq!(Lang::from_code("rus".to_string()), Some(Lang::Rus));
assert_eq!(Lang::from_code("ukr"), Some(Lang::Ukr));
assert_eq!(Lang::from_code("ENG"), Some(Lang::Eng));
assert_eq!(Lang::from_code("oops"), None);
}
#[test]
fn test_code() {
assert_eq!(Lang::Spa.code(), "spa");
}
#[test]
fn test_name() {
assert_eq!(Lang::Rus.name(), "Русский");
assert_eq!(Lang::Spa.name(), "Español");
assert_eq!(Lang::Epo.name(), "Esperanto");
}
#[test]
fn test_eng_name() {
assert_eq!(Lang::Spa.eng_name(), "Spanish");
assert_eq!(Lang::Epo.eng_name(), "Esperanto");
assert_eq!(Lang::Rus.eng_name(), "Russian");
}
#[test]
fn test_all() {
assert_eq!(Lang::all().len(), 67);
let all = Lang::all();
assert!(all.contains(&Lang::Ukr));
assert!(all.contains(&Lang::Swe));
}
#[test]
fn test_from_str() {
for &lang in Lang::all() {
let s = lang.code();
assert_eq!(s.parse::<Lang>().unwrap(), lang);
assert_eq!(s.to_lowercase().parse::<Lang>().unwrap(), lang);
assert_eq!(s.to_uppercase().parse::<Lang>().unwrap(), lang);
}
let result = "xyz".parse::<Lang>();
assert!(matches!(result, Err(Error::ParseLang(_))));
}
}