Skip to main content

holodeck_simctl_core/models/
language_option.rs

1/// A human-readable language/region pairing for the TUI's launch-language
2/// picker, e.g. "Portuguese (Brazil)" → `pt-BR`. Curated rather than
3/// exhaustive: the common languages and regional variants engineers actually
4/// test with, not every BCP-47 tag iOS recognizes. The CLI's `--language`
5/// flag bypasses this table entirely and takes a raw tag, so it is unaffected
6/// by what is or isn't listed here.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct LanguageOption {
9    pub display_name: &'static str,
10    pub bcp47: &'static str,
11}
12
13impl LanguageOption {
14    pub const ALL: &'static [LanguageOption] = &[
15        LanguageOption { display_name: "English (US)", bcp47: "en-US" },
16        LanguageOption { display_name: "English (UK)", bcp47: "en-GB" },
17        LanguageOption { display_name: "English (Australia)", bcp47: "en-AU" },
18        LanguageOption { display_name: "English (Canada)", bcp47: "en-CA" },
19        LanguageOption { display_name: "English (India)", bcp47: "en-IN" },
20        LanguageOption { display_name: "Spanish (Spain)", bcp47: "es-ES" },
21        LanguageOption { display_name: "Spanish (Mexico)", bcp47: "es-MX" },
22        LanguageOption { display_name: "Spanish (Latin America)", bcp47: "es-419" },
23        LanguageOption { display_name: "Portuguese (Brazil)", bcp47: "pt-BR" },
24        LanguageOption { display_name: "Portuguese (Portugal)", bcp47: "pt-PT" },
25        LanguageOption { display_name: "French (France)", bcp47: "fr-FR" },
26        LanguageOption { display_name: "French (Canada)", bcp47: "fr-CA" },
27        LanguageOption { display_name: "German (Germany)", bcp47: "de-DE" },
28        LanguageOption { display_name: "German (Austria)", bcp47: "de-AT" },
29        LanguageOption { display_name: "Italian (Italy)", bcp47: "it-IT" },
30        LanguageOption { display_name: "Dutch (Netherlands)", bcp47: "nl-NL" },
31        LanguageOption { display_name: "Russian", bcp47: "ru-RU" },
32        LanguageOption { display_name: "Ukrainian", bcp47: "uk-UA" },
33        LanguageOption { display_name: "Polish", bcp47: "pl-PL" },
34        LanguageOption { display_name: "Czech", bcp47: "cs-CZ" },
35        LanguageOption { display_name: "Slovak", bcp47: "sk-SK" },
36        LanguageOption { display_name: "Hungarian", bcp47: "hu-HU" },
37        LanguageOption { display_name: "Romanian", bcp47: "ro-RO" },
38        LanguageOption { display_name: "Greek", bcp47: "el-GR" },
39        LanguageOption { display_name: "Turkish", bcp47: "tr-TR" },
40        LanguageOption { display_name: "Swedish", bcp47: "sv-SE" },
41        LanguageOption { display_name: "Norwegian Bokmål", bcp47: "nb-NO" },
42        LanguageOption { display_name: "Danish", bcp47: "da-DK" },
43        LanguageOption { display_name: "Finnish", bcp47: "fi-FI" },
44        LanguageOption { display_name: "Croatian", bcp47: "hr-HR" },
45        LanguageOption { display_name: "Arabic", bcp47: "ar-SA" },
46        LanguageOption { display_name: "Hebrew", bcp47: "he-IL" },
47        LanguageOption { display_name: "Hindi", bcp47: "hi-IN" },
48        LanguageOption { display_name: "Thai", bcp47: "th-TH" },
49        LanguageOption { display_name: "Vietnamese", bcp47: "vi-VN" },
50        LanguageOption { display_name: "Indonesian", bcp47: "id-ID" },
51        LanguageOption { display_name: "Japanese", bcp47: "ja-JP" },
52        LanguageOption { display_name: "Korean", bcp47: "ko-KR" },
53        LanguageOption { display_name: "Chinese (Simplified)", bcp47: "zh-Hans" },
54        LanguageOption { display_name: "Chinese (Traditional)", bcp47: "zh-Hant" },
55    ];
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn every_entry_has_a_non_empty_display_name_and_tag() {
64        for language in LanguageOption::ALL {
65            assert!(!language.display_name.is_empty());
66            assert!(!language.bcp47.is_empty());
67        }
68    }
69
70    #[test]
71    fn bcp47_tags_are_unique() {
72        let mut tags: Vec<&str> = LanguageOption::ALL.iter().map(|l| l.bcp47).collect();
73        tags.sort_unstable();
74        tags.dedup();
75        assert_eq!(tags.len(), LanguageOption::ALL.len());
76    }
77}