use crate::error::get_last_error;
use crate::string::{SpiceStr, SpiceString};
use crate::time::calendar::Calendar;
use crate::time::date_time::DateTime;
use crate::time::system::System;
use crate::time::Et;
use crate::with_spice_lock_or_panic;
use cspice_sys::{timout_c, SpiceDouble};
use std::fmt::{Display, Formatter};
use std::marker::PhantomData;
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct JulianDate<S: System> {
pub value: SpiceDouble,
scale: PhantomData<S>,
}
impl<S: System> From<SpiceDouble> for JulianDate<S> {
fn from(s: SpiceDouble) -> Self {
JulianDate::new(s)
}
}
impl<S: System> JulianDate<S> {
#[inline]
pub fn new(jd: SpiceDouble) -> Self {
Self {
value: jd,
scale: Default::default(),
}
}
}
impl<S: System> From<JulianDate<S>> for Et {
#[inline]
fn from(jd: JulianDate<S>) -> Self {
Et::from_string(format!("JD {} {}", S::system_name(), jd.value)).unwrap()
}
}
impl<S: System> From<Et> for JulianDate<S> {
#[inline]
fn from(et: Et) -> Self {
let pictur = SpiceString::from(format!("JULIAND.############# ::{}", S::system_name()));
let mut buffer = [0; 40];
with_spice_lock_or_panic(|| {
unsafe {
timout_c(
et.0,
pictur.as_mut_ptr(),
buffer.len() as i32,
buffer.as_mut_ptr(),
)
};
get_last_error().unwrap();
});
Self::new(SpiceStr::from_buffer(&buffer).as_str().parse().unwrap())
}
}
impl<C: Calendar, S: System> From<DateTime<C, S>> for JulianDate<S> {
#[inline]
fn from(dt: DateTime<C, S>) -> Self {
JulianDate::from(Et::from(dt))
}
}
impl<S: System> Display for JulianDate<S> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "JD {} {}", S::system_name(), self.value)
}
}