Coverage Report

Created: 2025-08-13 21:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/a220/proj/radnelac/src/display/tranquility.rs
Line
Count
Source
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5
use crate::calendar::HasIntercalaryDays;
6
use crate::calendar::Perennial;
7
use crate::calendar::ToFromCommonDate;
8
use crate::calendar::ToFromOrdinalDate;
9
use crate::calendar::Tranquility;
10
use crate::calendar::TranquilityComplementaryDay;
11
use crate::calendar::TranquilityMoment;
12
use crate::clock::ClockTime;
13
use crate::clock::TimeOfDay;
14
use crate::day_count::ToFixed;
15
use crate::display::prelude::PresetDisplay;
16
use crate::display::prelude::COMPL_ONLY;
17
use crate::display::prelude::LONG_COMPL;
18
use crate::display::prelude::LONG_DATE;
19
use crate::display::prelude::YEAR_COMPL;
20
use crate::display::prelude::YEAR_MDD;
21
use crate::display::private::fmt_days_since_epoch;
22
use crate::display::private::fmt_number;
23
use crate::display::private::fmt_quarter;
24
use crate::display::private::fmt_seconds_since_epoch;
25
use crate::display::private::fmt_string;
26
use crate::display::private::get_dict;
27
use crate::display::private::DisplayItem;
28
use crate::display::private::DisplayOptions;
29
use crate::display::private::NumericContent;
30
use crate::display::private::TextContent;
31
use crate::display::text::prelude::Language;
32
use crate::display::HHMMSS_COLON;
33
use std::fmt;
34
35
impl DisplayItem for Tranquility {
36
1
    fn supported_lang(lang: Language) -> bool {
37
1
        get_dict(lang).tranquility.as_ref().is_some()
38
1
    }
39
40
18.4k
    fn fmt_numeric(&self, n: NumericContent, opt: DisplayOptions) -> String {
41
18.4k
        match n {
42
            NumericContent::Month | NumericContent::DayOfMonth | NumericContent::Year => {
43
15.9k
                self.to_common_date().fmt_numeric(n, opt)
44
            }
45
512
            NumericContent::DayOfWeek => match self.weekday() {
46
512
                Some(d) => d.fmt_numeric(n, opt),
47
0
                None => "".to_string(),
48
            },
49
512
            NumericContent::DayOfYear => self.to_ordinal().fmt_numeric(n, opt),
50
            NumericContent::Hour1to12
51
            | NumericContent::Hour0to23
52
            | NumericContent::Minute
53
0
            | NumericContent::Second => self.convert::<TimeOfDay>().fmt_numeric(n, opt),
54
512
            NumericContent::SecondsSinceEpoch => fmt_seconds_since_epoch(*self, opt),
55
0
            NumericContent::Quarter => fmt_quarter(*self, opt),
56
512
            NumericContent::DaysSinceEpoch => fmt_days_since_epoch(*self, opt),
57
0
            NumericContent::ComplementaryDay => match self.complementary() {
58
0
                Some(d) => fmt_number(d as i8, opt),
59
0
                None => "".to_string(),
60
            },
61
512
            NumericContent::WeekOfYear => match self.try_week_of_year() {
62
512
                Some(w) => fmt_number(w as i8, opt),
63
0
                None => "".to_string(),
64
            },
65
        }
66
18.4k
    }
67
10.8k
    fn fmt_text(&self, t: TextContent, lang: Language, opt: DisplayOptions) -> String {
68
10.8k
        match (t, get_dict(lang).tranquility.as_ref()) {
69
3.61k
            (TextContent::MonthName, Some(dict)) => {
70
3.61k
                let months: [&str; 13] = [
71
3.61k
                    dict.archimedes,
72
3.61k
                    dict.brahe,
73
3.61k
                    dict.copernicus,
74
3.61k
                    dict.darwin,
75
3.61k
                    dict.einstein,
76
3.61k
                    dict.faraday,
77
3.61k
                    dict.galileo,
78
3.61k
                    dict.hippocrates,
79
3.61k
                    dict.imhotep,
80
3.61k
                    dict.jung,
81
3.61k
                    dict.kepler,
82
3.61k
                    dict.lavoisier,
83
3.61k
                    dict.mendel,
84
3.61k
                ];
85
3.61k
                let name = match self.try_month() {
86
3.61k
                    Some(m) => months[(m as usize) - 1],
87
2
                    None => "",
88
                };
89
3.61k
                fmt_string(name, opt)
90
            }
91
0
            (TextContent::DayOfMonthName, _) => fmt_string("", opt),
92
3.59k
            (TextContent::DayOfWeekName, _) => match self.weekday() {
93
3.59k
                Some(m) => m.fmt_text(t, lang, opt),
94
2
                None => fmt_string("", opt),
95
            },
96
            (TextContent::HalfDayName | TextContent::HalfDayAbbrev, _) => {
97
0
                self.convert::<TimeOfDay>().fmt_text(t, lang, opt)
98
            }
99
2.57k
            (TextContent::EraName, Some(dict)) => {
100
2.57k
                if self.year() > 0 {
101
1.31k
                    fmt_string(dict.after_tranquility_full, opt)
102
1.26k
                } else if self.year() < 0 {
103
1.26k
                    fmt_string(dict.before_tranquility_full, opt)
104
                } else {
105
0
                    "".to_string()
106
                }
107
            }
108
512
            (TextContent::EraAbbreviation, Some(dict)) => {
109
512
                if self.year() > 0 {
110
253
                    fmt_string(dict.after_tranquility_abr, opt)
111
259
                } else if self.year() < 0 {
112
259
                    fmt_string(dict.before_tranquility_abr, opt)
113
                } else {
114
0
                    "".to_string()
115
                }
116
            }
117
522
            (TextContent::ComplementaryDayName, Some(dict)) => {
118
522
                let compl: [&str; 3] = [dict.moon_landing_day, dict.armstrong_day, dict.aldrin_day];
119
522
                let name = match self.complementary() {
120
266
                    Some(d) => compl[d as usize],
121
256
                    None => "",
122
                };
123
522
                fmt_string(name, opt)
124
            }
125
0
            (_, _) => String::from(""),
126
        }
127
10.8k
    }
128
}
129
130
impl PresetDisplay for Tranquility {
131
2.57k
    fn long_date(&self) -> String {
132
2.57k
        let p = match self.complementary() {
133
2.57k
            None => LONG_DATE,
134
1
            Some(TranquilityComplementaryDay::MoonLandingDay) => COMPL_ONLY,
135
6
            Some(_) => LONG_COMPL,
136
        };
137
2.57k
        self.preset_str(Language::EN, p)
138
2.57k
    }
139
140
19
    fn short_date(&self) -> String {
141
19
        let p = match self.complementary() {
142
16
            None => YEAR_MDD,
143
3
            Some(_) => YEAR_COMPL,
144
        };
145
19
        self.preset_str(Language::EN, p)
146
19
    }
147
}
148
149
impl fmt::Display for Tranquility {
150
2.56k
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151
2.56k
        write!(f, "{}", self.long_date())
152
2.56k
    }
153
}
154
155
impl DisplayItem for TranquilityMoment {
156
1
    fn supported_lang(lang: Language) -> bool {
157
1
        Tranquility::supported_lang(lang) && ClockTime::supported_lang(lang)
158
1
    }
159
160
16.1k
    fn fmt_numeric(&self, n: NumericContent, opt: DisplayOptions) -> String {
161
16.1k
        match n {
162
            NumericContent::Hour1to12
163
            | NumericContent::Hour0to23
164
            | NumericContent::Minute
165
3.84k
            | NumericContent::Second => self.clone().time_of_day().fmt_numeric(n, opt),
166
12.2k
            _ => self.clone().date().fmt_numeric(n, opt),
167
        }
168
16.1k
    }
169
170
2.04k
    fn fmt_text(&self, t: TextContent, lang: Language, opt: DisplayOptions) -> String {
171
2.04k
        match (t, get_dict(lang).tranquility.as_ref()) {
172
            (TextContent::HalfDayName, _) | (TextContent::HalfDayAbbrev, _) => {
173
0
                self.clone().time_of_day().fmt_text(t, lang, opt)
174
            }
175
0
            (TextContent::EraName, Some(dict)) => {
176
0
                if self.is_after_tranquility() {
177
0
                    fmt_string(dict.after_tranquility_full, opt)
178
                } else {
179
0
                    fmt_string(dict.before_tranquility_full, opt)
180
                }
181
            }
182
512
            (TextContent::EraAbbreviation, Some(dict)) => {
183
512
                if self.is_after_tranquility() {
184
253
                    fmt_string(dict.after_tranquility_abr, opt)
185
                } else {
186
259
                    fmt_string(dict.before_tranquility_abr, opt)
187
                }
188
            }
189
190
1.53k
            _ => self.clone().date().fmt_text(t, lang, opt),
191
        }
192
2.04k
    }
193
}
194
195
impl PresetDisplay for TranquilityMoment {
196
19
    fn long_date(&self) -> String {
197
19
        self.clone().date().long_date()
198
19
    }
199
200
19
    fn short_date(&self) -> String {
201
19
        self.clone().date().short_date()
202
19
    }
203
}
204
205
impl fmt::Display for TranquilityMoment {
206
1.28k
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
207
1.28k
        write!(f, "{} ", self.preset_str(Language::EN, HHMMSS_COLON));
208
1.28k
        self.date().fmt(f)
209
1.28k
    }
210
}
211
212
#[cfg(test)]
213
mod tests {
214
    use super::*;
215
    use crate::calendar::CommonDate;
216
217
    #[test]
218
1
    fn expected_languages() {
219
1
        assert!(TranquilityMoment::supported_lang(Language::EN));
220
1
    }
221
222
    #[test]
223
1
    fn long_date() {
224
1
        let d_list = [
225
1
            (CommonDate::new(0, 0, 0), "Moon Landing Day"),
226
1
            (
227
1
                CommonDate::new(1, 1, 1),
228
1
                "Friday Archimedes 1, 1 After Tranquility",
229
1
            ),
230
1
            (
231
1
                CommonDate::new(2, 2, 2),
232
1
                "Saturday Brahe 2, 2 After Tranquility",
233
1
            ),
234
1
            (
235
1
                CommonDate::new(3, 3, 3),
236
1
                "Sunday Copernicus 3, 3 After Tranquility",
237
1
            ),
238
1
            (
239
1
                CommonDate::new(4, 4, 4),
240
1
                "Monday Darwin 4, 4 After Tranquility",
241
1
            ),
242
1
            (
243
1
                CommonDate::new(5, 5, 5),
244
1
                "Tuesday Einstein 5, 5 After Tranquility",
245
1
            ),
246
1
            (
247
1
                CommonDate::new(6, 6, 6),
248
1
                "Wednesday Faraday 6, 6 After Tranquility",
249
1
            ),
250
1
            (
251
1
                CommonDate::new(7, 7, 7),
252
1
                "Thursday Galileo 7, 7 After Tranquility",
253
1
            ),
254
1
            (
255
1
                CommonDate::new(8, 8, 8),
256
1
                "Friday Hippocrates 8, 8 After Tranquility",
257
1
            ),
258
1
            (
259
1
                CommonDate::new(9, 9, 9),
260
1
                "Saturday Imhotep 9, 9 After Tranquility",
261
1
            ),
262
1
            (
263
1
                CommonDate::new(10, 10, 10),
264
1
                "Sunday Jung 10, 10 After Tranquility",
265
1
            ),
266
1
            (
267
1
                CommonDate::new(11, 11, 11),
268
1
                "Monday Kepler 11, 11 After Tranquility",
269
1
            ),
270
1
            (
271
1
                CommonDate::new(12, 12, 12),
272
1
                "Tuesday Lavoisier 12, 12 After Tranquility",
273
1
            ),
274
1
            (
275
1
                CommonDate::new(-1, 13, 28),
276
1
                "Thursday Mendel 28, 1 Before Tranquility",
277
1
            ),
278
1
            (
279
1
                CommonDate::new(-2, 0, 1),
280
1
                "Armstrong Day, 2 Before Tranquility",
281
1
            ),
282
1
            (
283
1
                CommonDate::new(31, 8, 27),
284
1
                "Wednesday Hippocrates 27, 31 After Tranquility",
285
1
            ),
286
1
            (
287
1
                CommonDate::new(31, 0, 2),
288
1
                "Aldrin Day, 31 After Tranquility",
289
1
            ),
290
1
            (
291
1
                CommonDate::new(31, 8, 28),
292
1
                "Thursday Hippocrates 28, 31 After Tranquility",
293
1
            ),
294
1
            (
295
1
                CommonDate::new(56, 4, 1),
296
1
                "Friday Darwin 1, 56 After Tranquility",
297
1
            ),
298
1
        ];
299
20
        for 
item19
in d_list {
300
19
            let d = TranquilityMoment::try_from_common_date(item.0).unwrap();
301
19
            let s = d.long_date();
302
19
            assert_eq!(s, item.1);
303
        }
304
1
    }
305
306
    #[test]
307
1
    fn short_date() {
308
1
        let d_list = [
309
1
            (CommonDate::new(0, 0, 0), "0-MOO"),
310
1
            (CommonDate::new(1, 1, 1), "1-A01"),
311
1
            (CommonDate::new(2, 2, 2), "2-B02"),
312
1
            (CommonDate::new(3, 3, 3), "3-C03"),
313
1
            (CommonDate::new(4, 4, 4), "4-D04"),
314
1
            (CommonDate::new(5, 5, 5), "5-E05"),
315
1
            (CommonDate::new(6, 6, 6), "6-F06"),
316
1
            (CommonDate::new(7, 7, 7), "7-G07"),
317
1
            (CommonDate::new(8, 8, 8), "8-H08"),
318
1
            (CommonDate::new(9, 9, 9), "9-I09"),
319
1
            (CommonDate::new(10, 10, 10), "10-J10"),
320
1
            (CommonDate::new(11, 11, 11), "11-K11"),
321
1
            (CommonDate::new(12, 12, 12), "12-L12"),
322
1
            (CommonDate::new(-1, 13, 28), "-1-M28"),
323
1
            (CommonDate::new(-2, 0, 1), "-2-ARM"),
324
1
            (CommonDate::new(31, 8, 27), "31-H27"),
325
1
            (CommonDate::new(31, 0, 2), "31-ALD"),
326
1
            (CommonDate::new(31, 8, 28), "31-H28"),
327
1
            (CommonDate::new(56, 4, 1), "56-D01"),
328
1
        ];
329
20
        for 
item19
in d_list {
330
19
            let d = TranquilityMoment::try_from_common_date(item.0).unwrap();
331
19
            let s = d.short_date();
332
19
            assert_eq!(s, item.1);
333
        }
334
1
    }
335
}