flams_ontology/
languages.rs

1use std::fmt::Display;
2use std::path::Path;
3use std::str::FromStr;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
8#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
9#[non_exhaustive]
10pub enum Language {
11    #[default]
12    #[cfg_attr(feature = "serde", serde(rename = "en"))]
13    English,
14    #[cfg_attr(feature = "serde", serde(rename = "de"))]
15    German,
16    #[cfg_attr(feature = "serde", serde(rename = "fr"))]
17    French,
18    #[cfg_attr(feature = "serde", serde(rename = "ro"))]
19    Romanian,
20    #[cfg_attr(feature = "serde", serde(rename = "ar"))]
21    Arabic,
22    #[cfg_attr(feature = "serde", serde(rename = "bg"))]
23    Bulgarian,
24    #[cfg_attr(feature = "serde", serde(rename = "ru"))]
25    Russian,
26    #[cfg_attr(feature = "serde", serde(rename = "fi"))]
27    Finnish,
28    #[cfg_attr(feature = "serde", serde(rename = "tr"))]
29    Turkish,
30    #[cfg_attr(feature = "serde", serde(rename = "sl"))]
31    Slovenian,
32}
33impl Language {
34    pub const SEPARATOR: char = 'l';
35    #[inline]
36    fn check(s: &str) -> Self {
37        if s.len() < 3 { return Self::default()}
38        match &s[s.len() - 3..] {
39            ".en" => Self::English,
40            ".de" => Self::German,
41            ".fr" => Self::French,
42            ".ro" => Self::Romanian,
43            ".ar" => Self::Arabic,
44            ".bg" => Self::Bulgarian,
45            ".ru" => Self::Russian,
46            ".fi" => Self::Finnish,
47            ".tr" => Self::Turkish,
48            ".sl" => Self::Slovenian,
49            _ => Self::default(),
50        }
51    }
52    #[must_use]
53    pub fn from_rel_path(mut s: &str) -> Self {
54        s = s.strip_suffix(".tex").unwrap_or(s);
55        Self::check(s)
56    }
57    pub fn from_file(path: &Path) -> Self {
58        path.file_stem()
59            .and_then(|s| s.to_str())
60            .map_or_else(Self::default, Self::check)
61    }
62
63    #[must_use]
64    pub const fn flag_unicode(&self) -> &'static str {
65        match self {
66            Self::English => "🇬🇧",
67            Self::German => "🇩🇪",
68            Self::French => "🇫🇷",
69            Self::Romanian => "🇷🇴",
70            Self::Arabic => "🇦🇪",
71            Self::Bulgarian => "🇧🇬",
72            Self::Russian => "🇷🇺",
73            Self::Finnish => "🇫🇮",
74            Self::Turkish => "🇹🇷",
75            Self::Slovenian => "🇸🇮",
76        }
77    }
78
79    #[must_use]
80    pub const fn flag_svg(&self) -> &'static str {
81        // https://flagicons.lipis.dev/
82        match self {
83            Self::English => r##"<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-gb" viewBox="0 0 640 480">
84  <path fill="#012169" d="M0 0h640v480H0z"/>
85  <path fill="#FFF" d="m75 0 244 181L562 0h78v62L400 241l240 178v61h-80L320 301 81 480H0v-60l239-178L0 64V0z"/>
86  <path fill="#C8102E" d="m424 281 216 159v40L369 281zm-184 20 6 35L54 480H0zM640 0v3L391 191l2-44L590 0zM0 0l239 176h-60L0 42z"/>
87  <path fill="#FFF" d="M241 0v480h160V0zM0 160v160h640V160z"/>
88  <path fill="#C8102E" d="M0 193v96h640v-96zM273 0v480h96V0z"/>
89</svg>"##,
90            Self::German => r##"<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-de" viewBox="0 0 640 480">
91  <path fill="#fc0" d="M0 320h640v160H0z"/>
92  <path fill="#000001" d="M0 0h640v160H0z"/>
93  <path fill="red" d="M0 160h640v160H0z"/>
94</svg>
95"##,
96            Self::French => r##"
97<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-fr" viewBox="0 0 640 480">
98  <path fill="#fff" d="M0 0h640v480H0z"/>
99  <path fill="#000091" d="M0 0h213.3v480H0z"/>
100  <path fill="#e1000f" d="M426.7 0H640v480H426.7z"/>
101</svg>
102"##,
103            Self::Romanian => r##"
104<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-ro" viewBox="0 0 640 480">
105  <g fill-rule="evenodd" stroke-width="1pt">
106    <path fill="#00319c" d="M0 0h213.3v480H0z"/>
107    <path fill="#ffde00" d="M213.3 0h213.4v480H213.3z"/>
108    <path fill="#de2110" d="M426.7 0H640v480H426.7z"/>
109  </g>
110</svg>
111"##,
112            Self::Arabic => r##"
113<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-ae" viewBox="0 0 640 480">
114  <path fill="#00732f" d="M0 0h640v160H0z"/>
115  <path fill="#fff" d="M0 160h640v160H0z"/>
116  <path fill="#000001" d="M0 320h640v160H0z"/>
117  <path fill="red" d="M0 0h220v480H0z"/>
118</svg>
119"##,
120            Self::Bulgarian => r##"<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-bg" viewBox="0 0 640 480">
121  <path fill="#fff" d="M0 0h640v160H0z"/>
122  <path fill="#00966e" d="M0 160h640v160H0z"/>
123  <path fill="#d62612" d="M0 320h640v160H0z"/>
124</svg>"##,
125            Self::Russian => r##"
126<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-ru" viewBox="0 0 640 480">
127  <path fill="#fff" d="M0 0h640v160H0z"/>
128  <path fill="#0039a6" d="M0 160h640v160H0z"/>
129  <path fill="#d52b1e" d="M0 320h640v160H0z"/>
130</svg>"##,
131            Self::Finnish => r##"<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-fi" viewBox="0 0 640 480">
132  <path fill="#fff" d="M0 0h640v480H0z"/>
133  <path fill="#002f6c" d="M0 174.5h640v131H0z"/>
134  <path fill="#002f6c" d="M175.5 0h130.9v480h-131z"/>
135</svg>"##,
136            Self::Turkish => r##"
137<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-tr" viewBox="0 0 640 480">
138  <g fill-rule="evenodd">
139    <path fill="#e30a17" d="M0 0h640v480H0z"/>
140    <path fill="#fff" d="M407 247.5c0 66.2-54.6 119.9-122 119.9s-122-53.7-122-120 54.6-119.8 122-119.8 122 53.7 122 119.9"/>
141    <path fill="#e30a17" d="M413 247.5c0 53-43.6 95.9-97.5 95.9s-97.6-43-97.6-96 43.7-95.8 97.6-95.8 97.6 42.9 97.6 95.9z"/>
142    <path fill="#fff" d="m430.7 191.5-1 44.3-41.3 11.2 40.8 14.5-1 40.7 26.5-31.8 40.2 14-23.2-34.1 28.3-33.9-43.5 12-25.8-37z"/>
143  </g>
144</svg>
145"##,
146            Self::Slovenian => r##"
147<svg width="1.5em" xmlns="http://www.w3.org/2000/svg" id="flag-icons-si" viewBox="0 0 640 480">
148  <defs>
149    <clipPath id="si-a">
150      <path fill-opacity=".7" d="M-15 0h682.6v512H-15.1z"/>
151    </clipPath>
152  </defs>
153  <g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#si-a)" transform="translate(14.1)scale(.9375)">
154    <path fill="#fff" d="M-62 0H962v512H-62z"/>
155    <path fill="#d50000" d="M-62 341.3H962V512H-62z"/>
156    <path fill="#0000bf" d="M-62 170.7H962v170.6H-62z"/>
157    <path fill="#d50000" d="M228.4 93c-4 61.6-6.4 95.4-15.7 111-10.2 16.8-20 29.1-59.7 44-39.6-14.9-49.4-27.2-59.6-44-9.4-15.6-11.7-49.4-15.7-111l5.8-2c11.8-3.6 20.6-6.5 27.1-7.8 9.3-2 17.3-4.2 42.3-4.7 25 .4 33 2.8 42.3 4.8 6.4 1.4 15.6 4 27.3 7.7z"/>
158    <path fill="#0000bf" d="M222.6 91c-3.8 61.5-7 89.7-12 103.2-9.6 23.2-24.8 35.9-57.6 48-32.8-12.1-48-24.8-57.7-48-5-13.6-8-41.7-11.8-103.3 11.6-3.6 20.6-6.4 27.1-7.7 9.3-2 17.3-4.3 42.3-4.7 25 .4 33 2.7 42.3 4.7a284 284 0 0 1 27.4 7.7z"/>
159    <path fill="#ffdf00" d="m153 109.8 1.5 3.7 7 1-4.5 2.7 4.3 2.9-6.3 1-2 3.4-2-3.5-6-.8 4-3-4.2-2.7 6.7-1z"/>
160    <path fill="#fff" d="m208.3 179.6-3.9-3-2.7-4.6-5.4-4.7-2.9-4.7-5.4-4.9-2.6-4.7-3-2.3-1.8-1.9-5 4.3-2.6 4.7-3.3 3-3.7-2.9-2.7-4.8-10.3-18.3-10.3 18.3-2.7 4.8-3.7 2.9-3.3-3-2.7-4.7-4.9-4.3-1.9 1.8-2.9 2.4-2.6 4.7-5.4 4.9-2.9 4.7-5.4 4.7-2.7 4.6-3.9 3a65.8 65.8 0 0 0 18.6 36.3 107 107 0 0 0 36.6 20.5 104.1 104.1 0 0 0 36.8-20.5c5.8-6 16.6-19.3 18.6-36.3"/>
161    <path fill="#ffdf00" d="m169.4 83.9 1.6 3.7 7 1-4.6 2.7 4.4 2.9-6.3 1-2 3.4-2-3.5-6-.8 4-3-4.2-2.7 6.6-1zm-33 0 1.6 3.7 7 .9-4.5 2.7 4.3 2.9-6.3 1-2 3.4-2-3.4-6-.9 4-3-4.2-2.7 6.7-1z"/>
162    <path fill="#0000bf" d="M199.7 203h-7.4l-7-.5-8.3-4h-9.4l-8.1 4-6.5.6-6.4-.6-8.1-4H129l-8.4 4-6.9.6-7.6-.1-3.6-6.2.1-.2 11.2 1.9 6.9-.5 8.3-4.1h9.4l8.2 4 6.4.6 6.5-.6 8.1-4h9.4l8.4 4 6.9.6 10.8-2 .2.4zm-86.4 9.5 7.4-.5 8.3-4h9.4l8.2 4 6.4.5 6.4-.5 8.2-4h9.4l8.3 4 7.5.5 4.8-6h-.1l-5.2 1.4-6.9-.5-8.3-4h-9.4l-8.2 4-6.4.6-6.5-.6-8.1-4H129l-8.4 4-6.9.6-5-1.3v.2l4.5 5.6z"/>
163  </g>
164</svg>
165"##,
166        }
167    }
168}
169impl Display for Language {
170    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
171        write!(f, "{}", Into::<&'static str>::into(*self))
172    }
173}
174impl From<Language> for &'static str {
175    fn from(value: Language) -> Self {
176        match value {
177            Language::English => "en",
178            Language::German => "de",
179            Language::French => "fr",
180            Language::Romanian => "ro",
181            Language::Arabic => "ar",
182            Language::Bulgarian => "bg",
183            Language::Russian => "ru",
184            Language::Finnish => "fi",
185            Language::Turkish => "tr",
186            Language::Slovenian => "sl",
187        }
188    }
189}
190impl FromStr for Language {
191    type Err = ();
192    fn from_str(s: &str) -> Result<Self, ()> {
193        match s {
194            "en" => Ok(Self::English),
195            "de" => Ok(Self::German),
196            "fr" => Ok(Self::French),
197            "ro" => Ok(Self::Romanian),
198            "ar" => Ok(Self::Arabic),
199            "bg" => Ok(Self::Bulgarian),
200            "ru" => Ok(Self::Russian),
201            "fi" => Ok(Self::Finnish),
202            "tr" => Ok(Self::Turkish),
203            "sl" => Ok(Self::Slovenian),
204            _ => Err(()),
205        }
206    }
207}