1use std::sync::RwLock;
9
10use crate::G11_safe::eraEcm06_safe;
11use crate::G1_safe::{eraAnp_safe, eraAnpm_safe};
12use crate::G23_safe::{eraNut80_safe, eraObl80_safe};
13use crate::G28_safe::eraRxp_safe;
14use crate::G29_safe::eraS2c_safe;
15use crate::G7_safe::eraC2s_safe;
16use crate::H1_safe::{eraLEAPSECOND, ERFA_D2PI, ERFA_DAS2R, ERFA_DJ00, ERFA_DJC};
17
18pub type ErfaResult<T> = Result<T, ()>;
19
20const G14_BUILTIN_LEAPSECONDS: &[eraLEAPSECOND] = &[
22 eraLEAPSECOND {
23 iyear: 1960,
24 month: 1,
25 delat: 1.4178180,
26 },
27 eraLEAPSECOND {
28 iyear: 1961,
29 month: 1,
30 delat: 1.4228180,
31 },
32 eraLEAPSECOND {
33 iyear: 1961,
34 month: 8,
35 delat: 1.3728180,
36 },
37 eraLEAPSECOND {
38 iyear: 1962,
39 month: 1,
40 delat: 1.8458580,
41 },
42 eraLEAPSECOND {
43 iyear: 1963,
44 month: 11,
45 delat: 1.9458580,
46 },
47 eraLEAPSECOND {
48 iyear: 1964,
49 month: 1,
50 delat: 3.2401300,
51 },
52 eraLEAPSECOND {
53 iyear: 1964,
54 month: 4,
55 delat: 3.3401300,
56 },
57 eraLEAPSECOND {
58 iyear: 1964,
59 month: 9,
60 delat: 3.4401300,
61 },
62 eraLEAPSECOND {
63 iyear: 1965,
64 month: 1,
65 delat: 3.5401300,
66 },
67 eraLEAPSECOND {
68 iyear: 1965,
69 month: 3,
70 delat: 3.6401300,
71 },
72 eraLEAPSECOND {
73 iyear: 1965,
74 month: 7,
75 delat: 3.7401300,
76 },
77 eraLEAPSECOND {
78 iyear: 1965,
79 month: 9,
80 delat: 3.8401300,
81 },
82 eraLEAPSECOND {
83 iyear: 1966,
84 month: 1,
85 delat: 4.3131700,
86 },
87 eraLEAPSECOND {
88 iyear: 1968,
89 month: 2,
90 delat: 4.2131700,
91 },
92 eraLEAPSECOND {
93 iyear: 1972,
94 month: 1,
95 delat: 10.0,
96 },
97 eraLEAPSECOND {
98 iyear: 1972,
99 month: 7,
100 delat: 11.0,
101 },
102 eraLEAPSECOND {
103 iyear: 1973,
104 month: 1,
105 delat: 12.0,
106 },
107 eraLEAPSECOND {
108 iyear: 1974,
109 month: 1,
110 delat: 13.0,
111 },
112 eraLEAPSECOND {
113 iyear: 1975,
114 month: 1,
115 delat: 14.0,
116 },
117 eraLEAPSECOND {
118 iyear: 1976,
119 month: 1,
120 delat: 15.0,
121 },
122 eraLEAPSECOND {
123 iyear: 1977,
124 month: 1,
125 delat: 16.0,
126 },
127 eraLEAPSECOND {
128 iyear: 1978,
129 month: 1,
130 delat: 17.0,
131 },
132 eraLEAPSECOND {
133 iyear: 1979,
134 month: 1,
135 delat: 18.0,
136 },
137 eraLEAPSECOND {
138 iyear: 1980,
139 month: 1,
140 delat: 19.0,
141 },
142 eraLEAPSECOND {
143 iyear: 1981,
144 month: 7,
145 delat: 20.0,
146 },
147 eraLEAPSECOND {
148 iyear: 1982,
149 month: 7,
150 delat: 21.0,
151 },
152 eraLEAPSECOND {
153 iyear: 1983,
154 month: 7,
155 delat: 22.0,
156 },
157 eraLEAPSECOND {
158 iyear: 1985,
159 month: 7,
160 delat: 23.0,
161 },
162 eraLEAPSECOND {
163 iyear: 1988,
164 month: 1,
165 delat: 24.0,
166 },
167 eraLEAPSECOND {
168 iyear: 1990,
169 month: 1,
170 delat: 25.0,
171 },
172 eraLEAPSECOND {
173 iyear: 1991,
174 month: 1,
175 delat: 26.0,
176 },
177 eraLEAPSECOND {
178 iyear: 1992,
179 month: 7,
180 delat: 27.0,
181 },
182 eraLEAPSECOND {
183 iyear: 1993,
184 month: 7,
185 delat: 28.0,
186 },
187 eraLEAPSECOND {
188 iyear: 1994,
189 month: 7,
190 delat: 29.0,
191 },
192 eraLEAPSECOND {
193 iyear: 1996,
194 month: 1,
195 delat: 30.0,
196 },
197 eraLEAPSECOND {
198 iyear: 1997,
199 month: 7,
200 delat: 31.0,
201 },
202 eraLEAPSECOND {
203 iyear: 1999,
204 month: 1,
205 delat: 32.0,
206 },
207 eraLEAPSECOND {
208 iyear: 2006,
209 month: 1,
210 delat: 33.0,
211 },
212 eraLEAPSECOND {
213 iyear: 2009,
214 month: 1,
215 delat: 34.0,
216 },
217 eraLEAPSECOND {
218 iyear: 2012,
219 month: 7,
220 delat: 35.0,
221 },
222 eraLEAPSECOND {
223 iyear: 2015,
224 month: 7,
225 delat: 36.0,
226 },
227 eraLEAPSECOND {
228 iyear: 2017,
229 month: 1,
230 delat: 37.0,
231 },
232];
233
234#[derive(Clone, Default)]
236struct LeapState {
237 ndat: i32,
238 table: Vec<eraLEAPSECOND>,
239}
240
241static LEAP_STATE: RwLock<LeapState> = RwLock::new(LeapState {
242 ndat: -1,
243 table: Vec::new(),
244});
245
246pub fn eraEqec06_safe(date1: f64, date2: f64, dr: f64, dd: f64) -> ErfaResult<(f64, f64)> {
249 let v1 = eraS2c_safe(dr, dd)?;
250 let mut rm = [[0.0_f64; 3]; 3];
251 eraEcm06_safe(date1, date2, &mut rm)?;
252 let v2 = eraRxp_safe(&rm, &v1)?;
253 let (a, b) = eraC2s_safe(&v2)?;
254 let dl = eraAnp_safe(a)?;
255 let db = eraAnpm_safe(b)?;
256 Ok((dl, db))
257}
258
259pub fn eraEqeq94_safe(date1: f64, date2: f64) -> ErfaResult<f64> {
262 let t = ((date1 - ERFA_DJ00) + date2) / ERFA_DJC;
263 let a = -5.0 * t;
264 let fmod1 = a - a.trunc();
265 let om = eraAnpm_safe(
266 (450_160.280 + (-482_890.539 + (7.455 + 0.008 * t) * t) * t) * ERFA_DAS2R
267 + fmod1 * ERFA_D2PI,
268 )?;
269 let (dpsi, _deps) = eraNut80_safe(date1, date2)?;
270 let eps0 = eraObl80_safe(date1, date2)?;
271 let ee = dpsi * eps0.cos() + ERFA_DAS2R * (0.00264 * om.sin() + 0.000_063 * (2.0 * om).sin());
272 Ok(ee)
273}
274
275pub fn eraEra00_safe(dj1: f64, dj2: f64) -> ErfaResult<f64> {
278 let (d1, d2) = if dj1 < dj2 { (dj1, dj2) } else { (dj2, dj1) };
279 let t = d1 + (d2 - ERFA_DJ00);
280 let f1 = d1 - d1.trunc();
281 let f2 = d2 - d2.trunc();
282 let f = f1 + f2;
283 let theta = eraAnp_safe(ERFA_D2PI * (f + 0.779_057_273_264_0 + 0.002_737_811_911_354_48 * t))?;
284 Ok(theta)
285}
286
287pub fn eraGetLeapSeconds_safe() -> ErfaResult<Vec<eraLEAPSECOND>> {
290 {
291 let guard = LEAP_STATE.read().map_err(|_| ())?;
292 if guard.ndat > 0 {
293 return Ok(guard.table.clone());
294 }
295 }
296 let _ = eraDatini_safe(G14_BUILTIN_LEAPSECONDS)?;
297 let guard = LEAP_STATE.read().map_err(|_| ())?;
298 if guard.ndat > 0 {
299 Ok(guard.table.clone())
300 } else {
301 Err(())
302 }
303}
304
305pub fn eraSetLeapSeconds_safe(table: &[eraLEAPSECOND]) -> ErfaResult<()> {
308 let mut guard = LEAP_STATE.write().map_err(|_| ())?;
309 if table.is_empty() {
310 guard.table.clear();
311 guard.ndat = 0;
312 } else {
313 guard.table = table.to_vec();
314 guard.ndat = guard.table.len() as i32;
315 }
316 Ok(())
317}
318
319pub fn eraDatini_safe(builtin: &[eraLEAPSECOND]) -> ErfaResult<Vec<eraLEAPSECOND>> {
322 let mut guard = LEAP_STATE.write().map_err(|_| ())?;
323 if guard.ndat <= 0 {
324 guard.table = builtin.to_vec();
325 guard.ndat = guard.table.len() as i32;
326 }
327 Ok(guard.table.clone())
328}
329
330pub fn eraVersion_safe() -> &'static str {
333 env!("CARGO_PKG_VERSION")
334}
335
336pub fn eraVersionMajor_safe() -> i32 {
338 let v = env!("CARGO_PKG_VERSION");
339 v.split('.')
340 .next()
341 .unwrap_or("0")
342 .parse::<i32>()
343 .unwrap_or(0)
344}
345
346pub fn eraVersionMinor_safe() -> i32 {
348 let v = env!("CARGO_PKG_VERSION");
349 v.split('.')
350 .nth(1)
351 .unwrap_or("0")
352 .parse::<i32>()
353 .unwrap_or(0)
354}
355
356pub fn eraVersionMicro_safe() -> i32 {
358 let v = env!("CARGO_PKG_VERSION");
359 v.split('.')
360 .nth(2)
361 .unwrap_or("0")
362 .parse::<i32>()
363 .unwrap_or(0)
364}
365
366pub fn eraSofaVersion_safe() -> &'static str {
368 "unknown"
369}