Skip to main content

orbital_date_pickers/shared/
datetime_locale_strings.rs

1//! Localized picker chrome strings resolved from a BCP-47 locale tag.
2
3/// User-facing strings for date/time picker chrome (calendar headers, weekdays, meridiem).
4#[derive(Clone, Debug, PartialEq, Eq)]
5pub struct DatetimeLocaleStrings {
6    /// Short weekday labels starting Sunday (`Sun`..=`Sat` in en-US).
7    pub weekday_short: [String; 7],
8    /// Short month labels (`Jan`..=`Dec` in en-US).
9    pub month_short: [String; 12],
10    /// First day of the week (`0` = Sunday, `1` = Monday).
11    pub first_day_of_week: u8,
12    pub today_label: String,
13    pub previous_month_label: String,
14    pub next_month_label: String,
15    pub am_label: String,
16    pub pm_label: String,
17}
18
19impl DatetimeLocaleStrings {
20    /// Default English (US) picker strings.
21    pub fn english() -> Self {
22        Self {
23            weekday_short: [
24                "Sun".into(),
25                "Mon".into(),
26                "Tue".into(),
27                "Wed".into(),
28                "Thu".into(),
29                "Fri".into(),
30                "Sat".into(),
31            ],
32            month_short: [
33                "Jan".into(),
34                "Feb".into(),
35                "Mar".into(),
36                "Apr".into(),
37                "May".into(),
38                "Jun".into(),
39                "Jul".into(),
40                "Aug".into(),
41                "Sep".into(),
42                "Oct".into(),
43                "Nov".into(),
44                "Dec".into(),
45            ],
46            first_day_of_week: 0,
47            today_label: "Today".into(),
48            previous_month_label: "Previous".into(),
49            next_month_label: "Next".into(),
50            am_label: "AM".into(),
51            pm_label: "PM".into(),
52        }
53    }
54
55    /// French locale preset for localization previews.
56    pub fn french() -> Self {
57        Self {
58            weekday_short: [
59                "dim.".into(),
60                "lun.".into(),
61                "mar.".into(),
62                "mer.".into(),
63                "jeu.".into(),
64                "ven.".into(),
65                "sam.".into(),
66            ],
67            month_short: [
68                "janv.".into(),
69                "févr.".into(),
70                "mars".into(),
71                "avr.".into(),
72                "mai".into(),
73                "juin".into(),
74                "juil.".into(),
75                "août".into(),
76                "sept.".into(),
77                "oct.".into(),
78                "nov.".into(),
79                "déc.".into(),
80            ],
81            first_day_of_week: 1,
82            today_label: "Aujourd'hui".into(),
83            previous_month_label: "Précédent".into(),
84            next_month_label: "Suivant".into(),
85            am_label: "AM".into(),
86            pm_label: "PM".into(),
87        }
88    }
89
90    /// Resolve strings for a BCP-47 locale tag (falls back to English).
91    pub fn for_tag(tag: &str) -> Self {
92        let normalized = tag.to_ascii_lowercase();
93        if normalized.starts_with("fr") {
94            Self::french()
95        } else {
96            Self::english()
97        }
98    }
99
100    /// Weekday header labels rotated so index `0` is [`first_day_of_week`](Self::first_day_of_week).
101    pub fn weekday_header_labels(&self) -> [String; 7] {
102        let start = self.first_day_of_week as usize % 7;
103        std::array::from_fn(|i| self.weekday_short[(start + i) % 7].clone())
104    }
105}