celestial_eop_data/
lib.rs1mod decompress;
2mod entry;
3
4pub use entry::EopEntry;
5
6pub fn c04_data() -> &'static [EopEntry] {
7 decompress::c04()
8}
9
10pub fn finals_data() -> &'static [EopEntry] {
11 decompress::finals()
12}
13
14pub fn combined_data() -> Vec<EopEntry> {
15 let c04 = c04_data();
16 let finals = finals_data();
17 let c04_max_mjd = c04.last().map(|e| e.mjd).unwrap_or(0.0);
18 let mut combined = c04.to_vec();
19 combined.extend(finals.iter().filter(|e| e.mjd > c04_max_mjd));
20 combined
21}
22
23pub fn data_time_span() -> (f64, f64) {
24 let combined = combined_data();
25 let first = combined.first().map(|e| e.mjd).unwrap_or(0.0);
26 let last = combined.last().map(|e| e.mjd).unwrap_or(0.0);
27 (first, last)
28}
29
30pub fn data_timestamp() -> &'static str {
31 include_str!(concat!(env!("OUT_DIR"), "/eop_timestamp.txt"))
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn c04_loads_enough_records() {
40 assert!(c04_data().len() > 20_000);
41 }
42
43 #[test]
44 fn finals_loads_enough_records() {
45 assert!(finals_data().len() > 10_000);
46 }
47
48 #[test]
49 fn combined_sorted_no_duplicates() {
50 let data = combined_data();
51 for pair in data.windows(2) {
52 assert!(pair[1].mjd > pair[0].mjd, "not sorted at MJD {}", pair[0].mjd);
53 }
54 }
55
56 #[test]
57 fn time_span_covers_expected_range() {
58 let (start, end) = data_time_span();
59 assert!(start <= 37665.0, "start MJD {} too late", start);
60 assert!(end >= 60000.0, "end MJD {} too early", end);
61 }
62
63 #[test]
64 fn known_c04_value() {
65 let data = c04_data();
66 let entry = data.iter().find(|e| (e.mjd - 58849.0).abs() < 0.01);
67 let entry = entry.expect("MJD 58849 not found in C04");
68 assert!(
69 (entry.x_p - 0.076614).abs() < 0.001,
70 "xp={}, expected ~0.076614",
71 entry.x_p,
72 );
73 }
74
75 #[test]
76 fn timestamp_is_valid_iso8601() {
77 let ts = data_timestamp();
78 assert_eq!(ts.len(), 10, "timestamp '{}' wrong length", ts);
79 assert_eq!(&ts[4..5], "-");
80 assert_eq!(&ts[7..8], "-");
81 ts[0..4].parse::<u32>().expect("bad year");
82 ts[5..7].parse::<u32>().expect("bad month");
83 ts[8..10].parse::<u32>().expect("bad day");
84 }
85}