use std::marker::PhantomData;
use crate::astro::eop::{EopProvider, EopValues, IersEop};
use crate::time::JulianDate;
#[cfg(not(feature = "de440"))]
use crate::calculus::ephemeris::Vsop87Ephemeris;
#[cfg(not(feature = "de440"))]
pub type DefaultEphemeris = Vsop87Ephemeris;
#[cfg(all(feature = "de440", not(siderust_mock_de440)))]
pub type DefaultEphemeris = crate::calculus::ephemeris::De440Ephemeris;
#[cfg(all(feature = "de440", siderust_mock_de440))]
pub type DefaultEphemeris = crate::calculus::ephemeris::Vsop87Ephemeris;
pub type DefaultEop = IersEop;
#[derive(Debug, Clone, Copy, Default)]
pub struct DefaultNutationModel;
#[derive(Debug, Clone)]
pub struct AstroContext<Eph = DefaultEphemeris, Eop = DefaultEop, Nut = DefaultNutationModel> {
_ephemeris: PhantomData<Eph>,
eop: Eop,
_nutation: PhantomData<Nut>,
}
impl<Eph, Eop: Default, Nut> Default for AstroContext<Eph, Eop, Nut> {
fn default() -> Self {
Self {
_ephemeris: PhantomData,
eop: Eop::default(),
_nutation: PhantomData,
}
}
}
impl AstroContext {
#[inline]
pub fn new() -> Self {
Self::default()
}
}
impl<Eph, Eop: Default, Nut> AstroContext<Eph, Eop, Nut> {
#[inline]
pub fn with_types() -> Self {
Self::default()
}
}
impl<Eph, Eop: EopProvider, Nut> AstroContext<Eph, Eop, Nut> {
#[inline]
pub fn eop_at(&self, jd_utc: JulianDate) -> EopValues {
self.eop.eop_at(jd_utc)
}
#[inline]
pub fn eop(&self) -> &Eop {
&self.eop
}
}
impl<Eop, Nut> AstroContext<DefaultEphemeris, Eop, Nut> {
#[inline]
pub const fn uses_default_ephemeris(&self) -> bool {
true
}
}
use crate::calculus::ephemeris::DynEphemeris;
pub struct DynAstroContext<Eop = DefaultEop> {
ephemeris: Box<dyn DynEphemeris>,
eop: Eop,
}
impl DynAstroContext<DefaultEop> {
pub fn with_ephemeris(eph: Box<dyn DynEphemeris>) -> Self {
Self {
ephemeris: eph,
eop: DefaultEop::default(),
}
}
}
impl<Eop: Default> DynAstroContext<Eop> {
pub fn with_ephemeris_and_eop(eph: Box<dyn DynEphemeris>, eop: Eop) -> Self {
Self {
ephemeris: eph,
eop,
}
}
}
impl<Eop: EopProvider> DynAstroContext<Eop> {
#[inline]
pub fn ephemeris(&self) -> &dyn DynEphemeris {
&*self.ephemeris
}
#[inline]
pub fn eop_at(&self, jd_utc: JulianDate) -> EopValues {
self.eop.eop_at(jd_utc)
}
#[inline]
pub fn eop(&self) -> &Eop {
&self.eop
}
}
impl<Eop> std::fmt::Debug for DynAstroContext<Eop>
where
Eop: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DynAstroContext")
.field("ephemeris", &"<dyn DynEphemeris>")
.field("eop", &self.eop)
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_context_creation() {
let ctx = AstroContext::new();
assert!(ctx.uses_default_ephemeris());
}
#[test]
fn test_context_default() {
let ctx: AstroContext = Default::default();
assert!(ctx.uses_default_ephemeris());
}
#[test]
fn test_context_with_types() {
let ctx: AstroContext<DefaultEphemeris, DefaultEop, DefaultNutationModel> =
AstroContext::with_types();
assert!(ctx.uses_default_ephemeris());
}
}