use thiserror::Error;
use crate::jplephem::kernel::SpiceKernel;
use crate::jplephem::PlanetState;
use crate::jplephem_ext::SpiceKernelExt;
use crate::time::Time;
#[derive(Debug, Error)]
pub enum PlanetError {
#[error("Planet not found: {0}")]
NotFound(String),
#[error("Data error: {0}")]
DataError(String),
#[error("Invalid time: {0}")]
TimeError(String),
#[error("Ephemeris error: {0}")]
EphemerisError(#[from] crate::jplephem::JplephemError),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Body {
Sun,
Mercury,
Venus,
Earth,
Moon,
Mars,
Jupiter,
Saturn,
Uranus,
Neptune,
Pluto,
}
impl Body {
pub fn name(&self) -> &'static str {
match self {
Body::Sun => "Sun",
Body::Mercury => "Mercury",
Body::Venus => "Venus",
Body::Earth => "Earth",
Body::Moon => "Moon",
Body::Mars => "Mars",
Body::Jupiter => "Jupiter",
Body::Saturn => "Saturn",
Body::Uranus => "Uranus",
Body::Neptune => "Neptune",
Body::Pluto => "Pluto",
}
}
pub fn naif_id(&self) -> i32 {
match self {
Body::Sun => 10,
Body::Mercury => 199,
Body::Venus => 299,
Body::Earth => 399,
Body::Moon => 301,
Body::Mars => 499,
Body::Jupiter => 599,
Body::Saturn => 699,
Body::Uranus => 799,
Body::Neptune => 899,
Body::Pluto => 999,
}
}
fn spice_name(&self) -> &'static str {
match self {
Body::Sun => "sun",
Body::Mercury => "mercury",
Body::Venus => "venus",
Body::Earth => "earth",
Body::Moon => "moon",
Body::Mars => "mars",
Body::Jupiter => "jupiter barycenter",
Body::Saturn => "saturn barycenter",
Body::Uranus => "uranus barycenter",
Body::Neptune => "neptune barycenter",
Body::Pluto => "pluto barycenter",
}
}
}
pub struct Ephemeris {
kernel: SpiceKernel,
}
impl Ephemeris {
pub fn from_kernel(kernel: SpiceKernel) -> Self {
Self { kernel }
}
pub fn get_state(&mut self, body: Body, time: &Time) -> Result<PlanetState, PlanetError> {
Ok(self.kernel.compute_at(body.spice_name(), time)?)
}
pub fn kernel(&self) -> &SpiceKernel {
&self.kernel
}
pub fn kernel_mut(&mut self) -> &mut SpiceKernel {
&mut self.kernel
}
pub fn ecliptic_state(
&mut self,
body: Body,
time: &Time,
) -> Result<crate::positions::ecliptic::EclipticStateVector, PlanetError> {
Ok(crate::positions::ecliptic::EclipticStateVector::compute(
&mut self.kernel,
body.spice_name(),
"sun",
time,
)?)
}
}