-
Notifications
You must be signed in to change notification settings - Fork 13
Open
Description
It is currently not possible to provide transformations from "builtin" time scales and reference frames to user-defined ones because of the orphan rule.
// This will not compile because both `ToScale` and `Tai` are owned by a foreign crate
impl ToScale<MyScale> for Tai {
fn offset(&self, scale: Tt, _dt: TimeDelta) -> TimeDelta {
...
}
}- Refactor time scale transformations: Refactor time scale transformation traits #239
- Refactor reference frame transformations
--
Here's a small POC for an alternative implementation which implements the trait on a third struct, an offset provider, instead of the Time struct (take 1) or the time scale struct (take 2) directly. That way a third-party crate can own an alternative provider struct implementing OffsetProvider and the builtin types are only type parameters which do not trigger the orphan rule.
trait TimeScale {}
#[derive(Copy,Clone,Debug)]
struct Tai;
#[derive(Copy,Clone,Debug)]
struct Tt;
impl TimeScale for Tai {}
impl TimeScale for Tt {}
trait OffsetProvider<Origin, Target>
where
Origin: TimeScale,
Target: TimeScale,
{
fn offset(&self, origin: Origin, target: Target, epoch: f64) -> f64;
}
struct DefaultOffsetProvider;
const D_TAI_TT: f64 = 32.184;
impl OffsetProvider<Tai, Tt> for DefaultOffsetProvider {
fn offset(&self, _origin: Tai, _target: Tt, _epoch: f64) -> f64 {
D_TAI_TT
}
}
impl OffsetProvider<Tt, Tai> for DefaultOffsetProvider {
fn offset(&self, _origin: Tt, _target: Tai, _epoch: f64) -> f64 {
-D_TAI_TT
}
}
#[derive(Debug)]
struct Time<T: TimeScale + Copy> {
scale: T,
epoch: f64,
}
impl<T: TimeScale + Copy> Time<T> {
fn to_scale<S: TimeScale + Copy>(&self, scale: S) -> Time<S>
where
DefaultOffsetProvider: OffsetProvider<T, S>,
{
self.to_scale_with_provider(scale, &DefaultOffsetProvider)
}
fn to_scale_with_provider<S: TimeScale + Copy, P: OffsetProvider<T, S>>(
&self,
scale: S,
p: &P,
) -> Time<S> {
Time {scale, epoch: self.epoch + p.offset(self.scale, scale, self.epoch) }
}
}
fn main() {
let offset = DefaultOffsetProvider.offset(Tai, Tt, 0.0);
println!("{}", offset);
let t = Time {
scale: Tai,
epoch: 0.0,
};
let t1 = t.to_scale(Tt);
println!("{:?}", t1)
}Metadata
Metadata
Assignees
Labels
No labels