eska_presentation/localization/
locale.rs1use std::{
4 env,
5 ffi::{OsStr, OsString},
6};
7
8#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
10pub enum Locale {
11 RuRu,
12 #[default]
13 EnUs,
14}
15
16impl Locale {
17 #[must_use]
19 pub fn from_locale_name(value: &str) -> Option<Self> {
20 let base = value
21 .split(['.', '@'])
22 .next()
23 .unwrap_or(value)
24 .replace('_', "-")
25 .to_ascii_lowercase();
26
27 match base.as_str() {
28 "ru" | "ru-ru" => Some(Self::RuRu),
29 "en" | "en-us" => Some(Self::EnUs),
30 _ => None,
31 }
32 }
33
34 #[must_use]
36 pub const fn as_str(self) -> &'static str {
37 match self {
38 Self::RuRu => "ru-RU",
39 Self::EnUs => "en-US",
40 }
41 }
42}
43
44#[must_use]
48pub fn resolve_locale(
49 cli_locale: Option<&str>,
50 environment_locale: Option<&str>,
51 system_locale: Option<&str>,
52) -> Locale {
53 cli_locale
54 .or(environment_locale)
55 .or(system_locale)
56 .and_then(Locale::from_locale_name)
57 .unwrap_or_default()
58}
59
60#[must_use]
62pub fn resolve_locale_from_environment(cli_locale: Option<&str>) -> Locale {
63 let environment_locale: Option<OsString> = env::var_os("ESKA_LANG");
64 let system_locale = sys_locale::get_locale();
65 resolve_locale(
66 cli_locale,
67 environment_locale.as_deref().and_then(OsStr::to_str),
68 system_locale.as_deref(),
69 )
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn normalizes_supported_locale_names() {
78 for value in ["ru", "ru-RU", "ru_RU", "ru_RU.UTF-8"] {
79 assert_eq!(Locale::from_locale_name(value), Some(Locale::RuRu));
80 }
81 for value in ["en", "en-US", "en_US", "en_US.UTF-8"] {
82 assert_eq!(Locale::from_locale_name(value), Some(Locale::EnUs));
83 }
84 }
85
86 #[test]
87 fn resolves_locale_in_priority_order() {
88 assert_eq!(
89 resolve_locale(Some("ru"), Some("en"), Some("en")),
90 Locale::RuRu
91 );
92 assert_eq!(resolve_locale(None, Some("ru"), Some("en")), Locale::RuRu);
93 assert_eq!(resolve_locale(None, None, Some("ru")), Locale::RuRu);
94 assert_eq!(resolve_locale(None, None, Some("de-DE")), Locale::EnUs);
95 assert_eq!(resolve_locale(None, None, None), Locale::EnUs);
96 }
97}