mod date_time;
mod julian_date;
pub mod calendar;
pub mod system;
pub use date_time::DateTime;
pub use julian_date::JulianDate;
use crate::common::{CALENDAR, SET};
use crate::error::get_last_error;
use crate::string::{SpiceString, StringParam};
use crate::{with_spice_lock_or_panic, Error};
use calendar::Calendar;
use cspice_sys::{str2et_c, timdef_c, timout_c, SpiceDouble, SpiceInt};
use derive_more::{From, Into};
use std::fmt::{Debug, Display, Formatter};
#[derive(Copy, Clone, Debug, PartialEq, From, Into)]
pub struct Et(pub SpiceDouble);
impl Display for Et {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "ET {}", self.0)
}
}
impl Et {
#[inline]
pub fn time_out<'p, P: Into<StringParam<'p>>>(
&self,
pictur: P,
out_length: usize,
) -> Result<String, Error> {
let mut buffer = vec![0; out_length];
with_spice_lock_or_panic(|| {
unsafe {
timout_c(
self.0,
pictur.into().as_mut_ptr(),
buffer.len() as SpiceInt,
buffer.as_mut_ptr(),
);
};
get_last_error()
})?;
Ok(SpiceString::from_buffer(buffer).to_string())
}
#[inline]
pub fn from_string<'p, P: Into<StringParam<'p>>>(string: P) -> Result<Self, Error> {
with_spice_lock_or_panic(|| {
let mut output = 0f64;
unsafe {
str2et_c(string.into().as_mut_ptr(), &mut output);
};
get_last_error()?;
Ok(Self(output))
})
}
}
#[inline]
pub fn set_default_calendar<C: Calendar>() {
let name = SpiceString::from(C::name());
with_spice_lock_or_panic(|| {
unsafe {
timdef_c(
SET.as_mut_ptr(),
CALENDAR.as_mut_ptr(),
0,
name.as_mut_ptr(),
);
};
get_last_error().unwrap();
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests::load_test_data;
use crate::time::calendar::{Gregorian, Mixed};
use crate::time::system::{Tdb, Utc};
#[test]
fn test_et_to_jd() {
load_test_data();
assert_eq!(
JulianDate::from(Et(0f64)),
JulianDate::<Tdb>::new(2451545.0)
);
}
#[test]
fn test_jd_to_date_time() {
load_test_data();
let et = Et::from(JulianDate::<Tdb>::new(1502273.5));
let dt = DateTime::<Mixed, _>::from_et(et, Tdb);
assert_eq!(dt, DateTime::new(-599, 1, 1, 0, 0, 0.0, Tdb));
}
#[test]
fn test_date_time_to_jd() {
load_test_data();
let jd = JulianDate::<Utc>::new(1502273.5);
assert_eq!(
JulianDate::from(DateTime::<Mixed, _>::new(
-599,
1,
1,
0,
0,
0.0,
Utc::default()
),),
jd
);
assert_eq!(
JulianDate::from(DateTime::<Mixed, _>::new(
-599,
1,
1,
3,
0,
0.0,
Utc::new(3, 0)
),),
jd
);
assert_eq!(
JulianDate::from(DateTime::<Gregorian, _>::new(
-600,
12,
26,
0,
0,
0.0,
Utc::default()
),),
jd
);
}
}