lox-frames 0.1.0-alpha.21

Reference frame transformations for the Lox ecosystem
Documentation
// SPDX-FileCopyrightText: 2025 Helge Eichhorn <git@helgeeichhorn.de>
//
// SPDX-License-Identifier: MPL-2.0

use std::convert::Infallible;

use lox_time::{
    Time,
    deltas::TimeDelta,
    offsets::OffsetProvider,
    time_scales::{ContinuousTimeScale, Tai},
    utc::{
        Utc,
        leap_seconds::{DefaultLeapSecondsProvider, LeapSecondsProvider},
    },
};

use crate::{
    iers::{Corrections, ReferenceSystem, polar_motion::PoleCoords},
    rotations::RotationProvider,
};

/// Default rotation provider with no EOP data (zero corrections, zero polar motion).
#[derive(Copy, Clone, Debug)]
pub struct DefaultRotationProvider;

impl OffsetProvider for DefaultRotationProvider {
    type Error = Infallible;

    fn tai_to_ut1(&self, delta: TimeDelta) -> Result<TimeDelta, Self::Error> {
        // UT1 is approximated by UTC, which is good to |UT1 - UTC| <= 0.9 s.
        // The contract is the offset *to* the target scale, i.e. UT1 - TAI,
        // so the leap-second count (TAI - UTC) has to be negated.
        let tai = Time::from_delta(Tai, delta);
        Ok(-DefaultLeapSecondsProvider.delta_tai_utc(tai))
    }

    fn ut1_to_tai(&self, delta: TimeDelta) -> Result<TimeDelta, Self::Error> {
        let utc = Utc::from_delta(delta);
        Ok(-DefaultLeapSecondsProvider.delta_utc_tai(utc))
    }
}

impl<T> RotationProvider<T> for DefaultRotationProvider
where
    T: ContinuousTimeScale,
{
    type EopError = Infallible;

    fn corrections(
        &self,
        _time: Time<T>,
        _sys: ReferenceSystem,
    ) -> Result<Corrections, Self::EopError> {
        Ok(Corrections::default())
    }

    fn pole_coords(&self, _time: Time<T>) -> Result<PoleCoords, Self::EopError> {
        Ok(PoleCoords::default())
    }
}