Skip to main content

klirr_core/models/l18n/
language.rs

1use core::fmt;
2
3use crate::prelude::*;
4
5#[derive(
6    Clone, Copy, PartialEq, Eq, Default, Hash, DeserializeFromStr, SerializeDisplay, EnumIter,
7)]
8pub enum Language {
9    /// πŸ‡¬πŸ‡§ English
10    #[default]
11    EN,
12    /// πŸ‡ΈπŸ‡ͺ Swedish
13    SV,
14}
15
16pub trait VariantIterable {
17    fn all() -> impl Iterator<Item = Self>;
18}
19
20impl VariantIterable for Language {
21    /// Returns all available languages as an iterator.
22    /// This can be used to iterate over all supported languages.
23    /// # Examples
24    /// ```
25    /// use klirr_core::prelude::*;
26    /// for lang in Language::all() {
27    ///     println!("Supported language: {}", lang);
28    /// }
29    /// ```
30    fn all() -> impl Iterator<Item = Self> {
31        Self::iter()
32    }
33}
34
35impl fmt::Debug for Language {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        let debug_str = match self {
38            Language::EN => "EN",
39            Language::SV => "SV",
40        };
41        write!(f, "{}", debug_str)
42    }
43}
44
45impl fmt::Display for Language {
46    /// Formats the language as a human-readable string.
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        let name = match self {
49            Language::EN => "english",
50            Language::SV => "swedish",
51        };
52        write!(f, "{}", name)
53    }
54}
55
56impl FromStr for Language {
57    type Err = String;
58
59    /// Parses a language code or name into a `Language` enum.
60    /// Accepts "en", "english", "sv", and "swedish" (case-insensitive).
61    ///
62    /// # Errors
63    /// Returns an error if the string does not match any known language.
64    ///
65    /// # Examples
66    /// ```
67    /// extern crate klirr_core;
68    /// use klirr_core::prelude::*;
69    /// let lang: Language = "en".parse().unwrap();
70    /// assert_eq!(lang, Language::EN);
71    /// let lang: Language = "swedish".parse().unwrap();
72    /// assert_eq!(lang, Language::SV);
73    /// ```
74    fn from_str(s: &str) -> Result<Self, Self::Err> {
75        match s.to_ascii_lowercase().as_str() {
76            "en" | "english" => Ok(Language::EN),
77            "sv" | "swedish" => Ok(Language::SV),
78            _ => Err(format!("unknown language code: {}", s)),
79        }
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86    use insta::assert_debug_snapshot;
87    use test_log::test;
88
89    #[test]
90    fn test_language_debug() {
91        assert_debug_snapshot!(Language::EN, @"EN");
92        assert_debug_snapshot!(Language::SV, @"SV");
93    }
94
95    #[test]
96    fn test_language_display() {
97        assert_eq!(Language::EN.to_string(), "english");
98        assert_eq!(Language::SV.to_string(), "swedish");
99    }
100
101    #[test]
102    fn test_language_from_str() {
103        assert_eq!("en".parse::<Language>().unwrap(), Language::EN);
104        assert_eq!("sv".parse::<Language>().unwrap(), Language::SV);
105        assert!("unknown".parse::<Language>().is_err());
106    }
107}