Skip to main content

atomcode_core/
locale.rs

1use std::fmt;
2use std::str::FromStr;
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub enum Locale {
8    #[serde(rename = "en")]
9    En,
10    #[serde(rename = "zh_CN")]
11    ZhCn,
12}
13
14impl Default for Locale {
15    fn default() -> Self {
16        Locale::En
17    }
18}
19
20impl fmt::Display for Locale {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            Locale::En => write!(f, "en"),
24            Locale::ZhCn => write!(f, "zh_CN"),
25        }
26    }
27}
28
29impl FromStr for Locale {
30    type Err = String;
31
32    fn from_str(s: &str) -> Result<Self, Self::Err> {
33        match s.to_ascii_lowercase().as_str() {
34            "en" | "english" => Ok(Locale::En),
35            "zh" | "zh_cn" | "zh-cn" | "chinese" | "简体中文"
36            | "zh_tw" | "zh-tw" | "zh_hk" | "zh-hk" | "繁體中文" => Ok(Locale::ZhCn),
37            other => Err(format!("unsupported locale: {other}")),
38        }
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[test]
47    fn display_round_trips_through_from_str() {
48        assert_eq!(Locale::En.to_string().parse::<Locale>().unwrap(), Locale::En);
49        assert_eq!(Locale::ZhCn.to_string().parse::<Locale>().unwrap(), Locale::ZhCn);
50    }
51
52    #[test]
53    fn from_str_accepts_common_aliases() {
54        assert_eq!("en".parse::<Locale>().unwrap(), Locale::En);
55        assert_eq!("English".parse::<Locale>().unwrap(), Locale::En);
56        assert_eq!("zh".parse::<Locale>().unwrap(), Locale::ZhCn);
57        assert_eq!("zh_CN".parse::<Locale>().unwrap(), Locale::ZhCn);
58        assert_eq!("zh-cn".parse::<Locale>().unwrap(), Locale::ZhCn);
59        assert_eq!("简体中文".parse::<Locale>().unwrap(), Locale::ZhCn);
60        // zh_TW / zh_HK fall back to ZhCn (no separate Traditional variant yet)
61        assert_eq!("zh_TW".parse::<Locale>().unwrap(), Locale::ZhCn);
62        assert_eq!("zh-tw".parse::<Locale>().unwrap(), Locale::ZhCn);
63        assert_eq!("zh_HK".parse::<Locale>().unwrap(), Locale::ZhCn);
64        assert_eq!("zh-hk".parse::<Locale>().unwrap(), Locale::ZhCn);
65        assert_eq!("繁體中文".parse::<Locale>().unwrap(), Locale::ZhCn);
66    }
67
68    #[test]
69    fn from_str_rejects_unknown() {
70        assert!("fr".parse::<Locale>().is_err());
71        assert!("".parse::<Locale>().is_err());
72    }
73
74    #[test]
75    fn serde_uses_short_keys() {
76        let s = serde_json::to_string(&Locale::ZhCn).unwrap();
77        assert_eq!(s, r#""zh_CN""#);
78        let parsed: Locale = serde_json::from_str(r#""en""#).unwrap();
79        assert_eq!(parsed, Locale::En);
80    }
81}