use lox_bodies::{CoordinateOrigin, NaifId, UndefinedOriginPropertyError};
use lox_core::coords::Ellipsoid;
use thiserror::Error;
use crate::iers::ReferenceSystem;
pub(crate) mod private {
pub struct Internal;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FrameKey {
Icrf,
J2000,
Cirf,
Tirf,
Itrf,
Teme,
Mod(ReferenceSystem),
Tod(ReferenceSystem),
Pef(ReferenceSystem),
Iau(NaifId),
}
pub trait ReferenceFrame {
fn name(&self) -> String;
fn abbreviation(&self) -> String;
#[doc(hidden)]
fn frame_key(&self, _: private::Internal) -> Option<FrameKey> {
None
}
}
pub fn frame_key(frame: &impl ReferenceFrame) -> Option<FrameKey> {
frame.frame_key(private::Internal)
}
pub trait QuasiInertial: ReferenceFrame {}
#[derive(Clone, Debug, Error, Eq, PartialEq)]
#[error("{0} is not a quasi-inertial frame")]
pub struct NonQuasiInertialFrameError(pub String);
pub trait TryQuasiInertial: ReferenceFrame {
fn try_quasi_inertial(&self) -> Result<(), NonQuasiInertialFrameError>;
}
impl<T: QuasiInertial> TryQuasiInertial for T {
fn try_quasi_inertial(&self) -> Result<(), NonQuasiInertialFrameError> {
Ok(())
}
}
pub trait BodyFixed: ReferenceFrame {
type Origin: CoordinateOrigin + Copy;
fn origin(&self) -> Self::Origin;
}
#[derive(Clone, Debug, Error)]
#[error("{0} is not a body-fixed frame")]
pub struct NonBodyFixedFrameError(pub String);
pub trait TryBodyFixed: ReferenceFrame {
type Origin: CoordinateOrigin + Copy;
fn try_body_fixed(&self) -> Result<(), NonBodyFixedFrameError>;
fn try_origin(&self) -> Result<Self::Origin, NonBodyFixedFrameError>;
}
impl<T: BodyFixed> TryBodyFixed for T {
type Origin = T::Origin;
fn try_body_fixed(&self) -> Result<(), NonBodyFixedFrameError> {
Ok(())
}
fn try_origin(&self) -> Result<Self::Origin, NonBodyFixedFrameError> {
Ok(self.origin())
}
}
pub trait ReferenceEllipsoid: BodyFixed {
fn reference_ellipsoid(&self) -> Ellipsoid;
}
pub trait TryReferenceEllipsoid: TryBodyFixed {
fn try_reference_ellipsoid(&self) -> Result<Ellipsoid, UndefinedReferenceEllipsoidError>;
}
impl<T> TryReferenceEllipsoid for T
where
T: ReferenceEllipsoid,
{
fn try_reference_ellipsoid(&self) -> Result<Ellipsoid, UndefinedReferenceEllipsoidError> {
Ok(self.reference_ellipsoid())
}
}
#[derive(Debug, thiserror::Error)]
pub enum UndefinedReferenceEllipsoidError {
#[error(transparent)]
NotBodyFixed(#[from] NonBodyFixedFrameError),
#[error(transparent)]
UndefinedSpheroid(#[from] UndefinedOriginPropertyError),
}