Skip to main content

lox_frames/rotations/
impls.rs

1// SPDX-FileCopyrightText: 2025 Helge Eichhorn <git@helgeeichhorn.de>
2//
3// SPDX-License-Identifier: MPL-2.0
4
5use lox_bodies::{DynOrigin, TryRotationalElements};
6use lox_time::{
7    Time,
8    offsets::TryOffset,
9    time_scales::{Tdb, TimeScale, Tt, Ut1},
10};
11
12use crate::{
13    Cirf, DynFrame, Iau, Icrf, Itrf, Tirf,
14    frames::{J2000, Mod, Pef, Teme, Tod},
15    iers::{Iers1996, Iers2003, Iers2010, ReferenceSystem},
16    rotations::{
17        DynRotationError, Rotation, RotationError, RotationProvider, TryComposedRotation,
18        TryRotation,
19    },
20};
21
22// ICRF <-> IAU
23
24impl<T, R, U> TryRotation<Icrf, Iau<R>, T> for U
25where
26    T: TimeScale + Copy,
27    R: TryRotationalElements + Copy,
28    U: RotationProvider<T> + TryOffset<T, Tdb>,
29{
30    type Error = RotationError;
31
32    fn try_rotation(
33        &self,
34        _origin: Icrf,
35        target: Iau<R>,
36        time: Time<T>,
37    ) -> Result<Rotation, Self::Error> {
38        self.icrf_to_iau(time, target)
39    }
40}
41
42impl<T, R, U> TryRotation<Iau<R>, Icrf, T> for U
43where
44    T: TimeScale + Copy,
45    R: TryRotationalElements + Copy,
46    U: RotationProvider<T> + TryOffset<T, Tdb>,
47{
48    type Error = RotationError;
49
50    fn try_rotation(
51        &self,
52        origin: Iau<R>,
53        _target: Icrf,
54        time: Time<T>,
55    ) -> Result<Rotation, Self::Error> {
56        self.iau_to_icrf(time, origin)
57    }
58}
59
60// ICRF <-> J2000
61
62impl<T, U> TryRotation<Icrf, J2000, T> for U
63where
64    T: TimeScale + Copy,
65    U: RotationProvider<T>,
66{
67    type Error = RotationError;
68
69    fn try_rotation(
70        &self,
71        _origin: Icrf,
72        _target: J2000,
73        _time: Time<T>,
74    ) -> Result<Rotation, Self::Error> {
75        Ok(self.icrf_to_j2000())
76    }
77}
78
79impl<T, U> TryRotation<J2000, Icrf, T> for U
80where
81    T: TimeScale + Copy,
82    U: RotationProvider<T>,
83{
84    type Error = RotationError;
85
86    fn try_rotation(
87        &self,
88        _origin: J2000,
89        _target: Icrf,
90        _time: Time<T>,
91    ) -> Result<Rotation, Self::Error> {
92        Ok(self.j2000_to_icrf())
93    }
94}
95
96// J2000 <-> MOD
97
98impl<T, U> TryRotation<J2000, Mod<Iers1996>, T> for U
99where
100    T: TimeScale + Copy,
101    U: RotationProvider<T> + TryOffset<T, Tt>,
102{
103    type Error = RotationError;
104
105    fn try_rotation(
106        &self,
107        _origin: J2000,
108        _target: Mod<Iers1996>,
109        time: Time<T>,
110    ) -> Result<Rotation, Self::Error> {
111        self.j2000_to_mod(time, ReferenceSystem::Iers1996)
112    }
113}
114
115impl<T, U> TryRotation<Mod<Iers1996>, J2000, T> for U
116where
117    T: TimeScale + Copy,
118    U: RotationProvider<T> + TryOffset<T, Tt>,
119{
120    type Error = RotationError;
121
122    fn try_rotation(
123        &self,
124        _origin: Mod<Iers1996>,
125        _target: J2000,
126        time: Time<T>,
127    ) -> Result<Rotation, Self::Error> {
128        self.mod_to_j2000(time, ReferenceSystem::Iers1996)
129    }
130}
131
132impl<T, U> TryRotation<J2000, Mod<Iers2003>, T> for U
133where
134    T: TimeScale + Copy,
135    U: RotationProvider<T> + TryOffset<T, Tt>,
136{
137    type Error = RotationError;
138
139    fn try_rotation(
140        &self,
141        _origin: J2000,
142        target: Mod<Iers2003>,
143        time: Time<T>,
144    ) -> Result<Rotation, Self::Error> {
145        self.j2000_to_mod(time, ReferenceSystem::Iers2003(target.0.0))
146    }
147}
148
149impl<T, U> TryRotation<Mod<Iers2003>, J2000, T> for U
150where
151    T: TimeScale + Copy,
152    U: RotationProvider<T> + TryOffset<T, Tt>,
153{
154    type Error = RotationError;
155
156    fn try_rotation(
157        &self,
158        origin: Mod<Iers2003>,
159        _target: J2000,
160        time: Time<T>,
161    ) -> Result<Rotation, Self::Error> {
162        self.mod_to_j2000(time, ReferenceSystem::Iers2003(origin.0.0))
163    }
164}
165
166impl<T, U> TryRotation<J2000, Mod<Iers2010>, T> for U
167where
168    T: TimeScale + Copy,
169    U: RotationProvider<T> + TryOffset<T, Tt>,
170{
171    type Error = RotationError;
172
173    fn try_rotation(
174        &self,
175        _origin: J2000,
176        _target: Mod<Iers2010>,
177        time: Time<T>,
178    ) -> Result<Rotation, Self::Error> {
179        self.j2000_to_mod(time, ReferenceSystem::Iers2010)
180    }
181}
182
183impl<T, U> TryRotation<Mod<Iers2010>, J2000, T> for U
184where
185    T: TimeScale + Copy,
186    U: RotationProvider<T> + TryOffset<T, Tt>,
187{
188    type Error = RotationError;
189
190    fn try_rotation(
191        &self,
192        _origin: Mod<Iers2010>,
193        _target: J2000,
194        time: Time<T>,
195    ) -> Result<Rotation, Self::Error> {
196        self.mod_to_j2000(time, ReferenceSystem::Iers2010)
197    }
198}
199
200// ICRF <-> ITRF
201
202impl<T, U> TryRotation<Icrf, Itrf, T> for U
203where
204    T: TimeScale + Copy,
205    U: RotationProvider<T> + TryOffset<T, Tdb> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
206{
207    type Error = RotationError;
208
209    fn try_rotation(
210        &self,
211        _origin: Icrf,
212        _target: Itrf,
213        time: Time<T>,
214    ) -> Result<Rotation, Self::Error> {
215        self.icrf_to_itrf(time)
216    }
217}
218
219impl<T, U> TryRotation<Itrf, Icrf, T> for U
220where
221    T: TimeScale + Copy,
222    U: RotationProvider<T> + TryOffset<T, Tdb> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
223{
224    type Error = RotationError;
225
226    fn try_rotation(
227        &self,
228        _origin: Itrf,
229        _target: Icrf,
230        time: Time<T>,
231    ) -> Result<Rotation, Self::Error> {
232        self.itrf_to_icrf(time)
233    }
234}
235
236// ICRF <-> CIRF
237
238impl<T, U> TryRotation<Icrf, Cirf, T> for U
239where
240    T: TimeScale + Copy,
241    U: RotationProvider<T> + TryOffset<T, Tdb>,
242{
243    type Error = RotationError;
244
245    fn try_rotation(
246        &self,
247        _origin: Icrf,
248        _target: Cirf,
249        time: Time<T>,
250    ) -> Result<Rotation, Self::Error> {
251        self.icrf_to_cirf(time)
252    }
253}
254
255impl<T, U> TryRotation<Cirf, Icrf, T> for U
256where
257    T: TimeScale + Copy,
258    U: RotationProvider<T> + TryOffset<T, Tdb>,
259{
260    type Error = RotationError;
261
262    fn try_rotation(
263        &self,
264        _origin: Cirf,
265        _target: Icrf,
266        time: Time<T>,
267    ) -> Result<Rotation, Self::Error> {
268        self.cirf_to_icrf(time)
269    }
270}
271
272// CIRF <-> TIRF
273
274impl<T, U> TryRotation<Cirf, Tirf, T> for U
275where
276    T: TimeScale + Copy,
277    U: RotationProvider<T> + TryOffset<T, Ut1>,
278{
279    type Error = RotationError;
280
281    fn try_rotation(
282        &self,
283        _origin: Cirf,
284        _target: Tirf,
285        time: Time<T>,
286    ) -> Result<Rotation, Self::Error> {
287        self.cirf_to_tirf(time)
288    }
289}
290
291impl<T, U> TryRotation<Tirf, Cirf, T> for U
292where
293    T: TimeScale + Copy,
294    U: RotationProvider<T> + TryOffset<T, Ut1>,
295{
296    type Error = RotationError;
297
298    fn try_rotation(
299        &self,
300        _origin: Tirf,
301        _target: Cirf,
302        time: Time<T>,
303    ) -> Result<Rotation, Self::Error> {
304        self.tirf_to_cirf(time)
305    }
306}
307
308// TIRF <-> ITRF
309
310impl<T, U> TryRotation<Tirf, Itrf, T> for U
311where
312    T: TimeScale + Copy,
313    U: RotationProvider<T> + TryOffset<T, Tt>,
314{
315    type Error = RotationError;
316
317    fn try_rotation(
318        &self,
319        _origin: Tirf,
320        _target: Itrf,
321        time: Time<T>,
322    ) -> Result<Rotation, Self::Error> {
323        self.tirf_to_itrf(time)
324    }
325}
326
327impl<T, U> TryRotation<Itrf, Tirf, T> for U
328where
329    T: TimeScale + Copy,
330    U: RotationProvider<T> + TryOffset<T, Tt>,
331{
332    type Error = RotationError;
333
334    fn try_rotation(
335        &self,
336        _origin: Itrf,
337        _target: Tirf,
338        time: Time<T>,
339    ) -> Result<Rotation, Self::Error> {
340        self.itrf_to_tirf(time)
341    }
342}
343
344// ICRF <-> MOD
345
346impl<T, U> TryRotation<Icrf, Mod<Iers1996>, T> for U
347where
348    T: TimeScale + Copy,
349    U: RotationProvider<T> + TryOffset<T, Tt>,
350{
351    type Error = RotationError;
352
353    fn try_rotation(
354        &self,
355        _origin: Icrf,
356        _target: Mod<Iers1996>,
357        time: Time<T>,
358    ) -> Result<Rotation, Self::Error> {
359        self.icrf_to_mod(time, ReferenceSystem::Iers1996)
360    }
361}
362
363impl<T, U> TryRotation<Mod<Iers1996>, Icrf, T> for U
364where
365    T: TimeScale + Copy,
366    U: RotationProvider<T> + TryOffset<T, Tt>,
367{
368    type Error = RotationError;
369
370    fn try_rotation(
371        &self,
372        _origin: Mod<Iers1996>,
373        _target: Icrf,
374        time: Time<T>,
375    ) -> Result<Rotation, Self::Error> {
376        self.mod_to_icrf(time, ReferenceSystem::Iers1996)
377    }
378}
379
380impl<T, U> TryRotation<Icrf, Mod<Iers2003>, T> for U
381where
382    T: TimeScale + Copy,
383    U: RotationProvider<T> + TryOffset<T, Tt>,
384{
385    type Error = RotationError;
386
387    fn try_rotation(
388        &self,
389        _origin: Icrf,
390        target: Mod<Iers2003>,
391        time: Time<T>,
392    ) -> Result<Rotation, Self::Error> {
393        self.icrf_to_mod(time, ReferenceSystem::Iers2003(target.0.0))
394    }
395}
396
397impl<T, U> TryRotation<Mod<Iers2003>, Icrf, T> for U
398where
399    T: TimeScale + Copy,
400    U: RotationProvider<T> + TryOffset<T, Tt>,
401{
402    type Error = RotationError;
403
404    fn try_rotation(
405        &self,
406        origin: Mod<Iers2003>,
407        _target: Icrf,
408        time: Time<T>,
409    ) -> Result<Rotation, Self::Error> {
410        self.mod_to_icrf(time, ReferenceSystem::Iers2003(origin.0.0))
411    }
412}
413
414impl<T, U> TryRotation<Icrf, Mod<Iers2010>, T> for U
415where
416    T: TimeScale + Copy,
417    U: RotationProvider<T> + TryOffset<T, Tt>,
418{
419    type Error = RotationError;
420
421    fn try_rotation(
422        &self,
423        _origin: Icrf,
424        _target: Mod<Iers2010>,
425        time: Time<T>,
426    ) -> Result<Rotation, Self::Error> {
427        self.icrf_to_mod(time, ReferenceSystem::Iers2010)
428    }
429}
430
431impl<T, U> TryRotation<Mod<Iers2010>, Icrf, T> for U
432where
433    T: TimeScale + Copy,
434    U: RotationProvider<T> + TryOffset<T, Tt>,
435{
436    type Error = RotationError;
437
438    fn try_rotation(
439        &self,
440        _origin: Mod<Iers2010>,
441        _target: Icrf,
442        time: Time<T>,
443    ) -> Result<Rotation, Self::Error> {
444        self.mod_to_icrf(time, ReferenceSystem::Iers2010)
445    }
446}
447
448// MOD <-> TOD
449
450impl<T, U> TryRotation<Mod<Iers1996>, Tod<Iers1996>, T> for U
451where
452    T: TimeScale + Copy,
453    U: RotationProvider<T> + TryOffset<T, Tdb>,
454{
455    type Error = RotationError;
456
457    fn try_rotation(
458        &self,
459        _origin: Mod<Iers1996>,
460        _target: Tod<Iers1996>,
461        time: Time<T>,
462    ) -> Result<Rotation, Self::Error> {
463        self.mod_to_tod(time, ReferenceSystem::Iers1996)
464    }
465}
466
467impl<T, U> TryRotation<Tod<Iers1996>, Mod<Iers1996>, T> for U
468where
469    T: TimeScale + Copy,
470    U: RotationProvider<T> + TryOffset<T, Tdb>,
471{
472    type Error = RotationError;
473
474    fn try_rotation(
475        &self,
476        _origin: Tod<Iers1996>,
477        _target: Mod<Iers1996>,
478        time: Time<T>,
479    ) -> Result<Rotation, Self::Error> {
480        self.tod_to_mod(time, ReferenceSystem::Iers1996)
481    }
482}
483
484impl<T, U> TryRotation<Mod<Iers2003>, Tod<Iers2003>, T> for U
485where
486    T: TimeScale + Copy,
487    U: RotationProvider<T> + TryOffset<T, Tdb>,
488{
489    type Error = RotationError;
490
491    fn try_rotation(
492        &self,
493        origin: Mod<Iers2003>,
494        _target: Tod<Iers2003>,
495        time: Time<T>,
496    ) -> Result<Rotation, Self::Error> {
497        self.mod_to_tod(time, ReferenceSystem::Iers2003(origin.0.0))
498    }
499}
500
501impl<T, U> TryRotation<Tod<Iers2003>, Mod<Iers2003>, T> for U
502where
503    T: TimeScale + Copy,
504    U: RotationProvider<T> + TryOffset<T, Tdb>,
505{
506    type Error = RotationError;
507
508    fn try_rotation(
509        &self,
510        origin: Tod<Iers2003>,
511        _target: Mod<Iers2003>,
512        time: Time<T>,
513    ) -> Result<Rotation, Self::Error> {
514        self.tod_to_mod(time, ReferenceSystem::Iers2003(origin.0.0))
515    }
516}
517
518impl<T, U> TryRotation<Mod<Iers2010>, Tod<Iers2010>, T> for U
519where
520    T: TimeScale + Copy,
521    U: RotationProvider<T> + TryOffset<T, Tdb>,
522{
523    type Error = RotationError;
524
525    fn try_rotation(
526        &self,
527        _origin: Mod<Iers2010>,
528        _target: Tod<Iers2010>,
529        time: Time<T>,
530    ) -> Result<Rotation, Self::Error> {
531        self.mod_to_tod(time, ReferenceSystem::Iers2010)
532    }
533}
534
535impl<T, U> TryRotation<Tod<Iers2010>, Mod<Iers2010>, T> for U
536where
537    T: TimeScale + Copy,
538    U: RotationProvider<T> + TryOffset<T, Tdb>,
539{
540    type Error = RotationError;
541
542    fn try_rotation(
543        &self,
544        _origin: Tod<Iers2010>,
545        _target: Mod<Iers2010>,
546        time: Time<T>,
547    ) -> Result<Rotation, Self::Error> {
548        self.tod_to_mod(time, ReferenceSystem::Iers2010)
549    }
550}
551
552// TOD <-> PEF
553
554impl<T, U> TryRotation<Tod<Iers1996>, Pef<Iers1996>, T> for U
555where
556    T: TimeScale + Copy,
557    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
558{
559    type Error = RotationError;
560
561    fn try_rotation(
562        &self,
563        _origin: Tod<Iers1996>,
564        _target: Pef<Iers1996>,
565        time: Time<T>,
566    ) -> Result<Rotation, Self::Error> {
567        self.tod_to_pef(time, ReferenceSystem::Iers1996)
568    }
569}
570
571impl<T, U> TryRotation<Pef<Iers1996>, Tod<Iers1996>, T> for U
572where
573    T: TimeScale + Copy,
574    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
575{
576    type Error = RotationError;
577
578    fn try_rotation(
579        &self,
580        _origin: Pef<Iers1996>,
581        _target: Tod<Iers1996>,
582        time: Time<T>,
583    ) -> Result<Rotation, Self::Error> {
584        self.pef_to_tod(time, ReferenceSystem::Iers1996)
585    }
586}
587
588impl<T, U> TryRotation<Tod<Iers2003>, Pef<Iers2003>, T> for U
589where
590    T: TimeScale + Copy,
591    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
592{
593    type Error = RotationError;
594
595    fn try_rotation(
596        &self,
597        origin: Tod<Iers2003>,
598        _target: Pef<Iers2003>,
599        time: Time<T>,
600    ) -> Result<Rotation, Self::Error> {
601        self.tod_to_pef(time, ReferenceSystem::Iers2003(origin.0.0))
602    }
603}
604
605impl<T, U> TryRotation<Pef<Iers2003>, Tod<Iers2003>, T> for U
606where
607    T: TimeScale + Copy,
608    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
609{
610    type Error = RotationError;
611
612    fn try_rotation(
613        &self,
614        origin: Pef<Iers2003>,
615        _target: Tod<Iers2003>,
616        time: Time<T>,
617    ) -> Result<Rotation, Self::Error> {
618        self.pef_to_tod(time, ReferenceSystem::Iers2003(origin.0.0))
619    }
620}
621
622impl<T, U> TryRotation<Tod<Iers2010>, Pef<Iers2010>, T> for U
623where
624    T: TimeScale + Copy,
625    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
626{
627    type Error = RotationError;
628
629    fn try_rotation(
630        &self,
631        _origin: Tod<Iers2010>,
632        _target: Pef<Iers2010>,
633        time: Time<T>,
634    ) -> Result<Rotation, Self::Error> {
635        self.tod_to_pef(time, ReferenceSystem::Iers2010)
636    }
637}
638
639impl<T, U> TryRotation<Pef<Iers2010>, Tod<Iers2010>, T> for U
640where
641    T: TimeScale + Copy,
642    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Ut1>,
643{
644    type Error = RotationError;
645
646    fn try_rotation(
647        &self,
648        _origin: Pef<Iers2010>,
649        _target: Tod<Iers2010>,
650        time: Time<T>,
651    ) -> Result<Rotation, Self::Error> {
652        self.pef_to_tod(time, ReferenceSystem::Iers2010)
653    }
654}
655
656// PEF <-> ITRF
657
658impl<T, U> TryRotation<Pef<Iers1996>, Itrf, T> for U
659where
660    T: TimeScale + Copy,
661    U: RotationProvider<T> + TryOffset<T, Tt>,
662{
663    type Error = RotationError;
664
665    fn try_rotation(
666        &self,
667        _origin: Pef<Iers1996>,
668        _target: Itrf,
669        time: Time<T>,
670    ) -> Result<Rotation, Self::Error> {
671        self.pef_to_itrf(time, ReferenceSystem::Iers1996)
672    }
673}
674
675impl<T, U> TryRotation<Itrf, Pef<Iers1996>, T> for U
676where
677    T: TimeScale + Copy,
678    U: RotationProvider<T> + TryOffset<T, Tt>,
679{
680    type Error = RotationError;
681
682    fn try_rotation(
683        &self,
684        _origin: Itrf,
685        _target: Pef<Iers1996>,
686        time: Time<T>,
687    ) -> Result<Rotation, Self::Error> {
688        self.itrf_to_pef(time, ReferenceSystem::Iers1996)
689    }
690}
691
692impl<T, U> TryRotation<Pef<Iers2003>, Itrf, T> for U
693where
694    T: TimeScale + Copy,
695    U: RotationProvider<T> + TryOffset<T, Tt>,
696{
697    type Error = RotationError;
698
699    fn try_rotation(
700        &self,
701        origin: Pef<Iers2003>,
702        _target: Itrf,
703        time: Time<T>,
704    ) -> Result<Rotation, Self::Error> {
705        self.pef_to_itrf(time, ReferenceSystem::Iers2003(origin.0.0))
706    }
707}
708
709impl<T, U> TryRotation<Itrf, Pef<Iers2003>, T> for U
710where
711    T: TimeScale + Copy,
712    U: RotationProvider<T> + TryOffset<T, Tt>,
713{
714    type Error = RotationError;
715
716    fn try_rotation(
717        &self,
718        _origin: Itrf,
719        target: Pef<Iers2003>,
720        time: Time<T>,
721    ) -> Result<Rotation, Self::Error> {
722        self.itrf_to_pef(time, ReferenceSystem::Iers2003(target.0.0))
723    }
724}
725
726impl<T, U> TryRotation<Pef<Iers2010>, Itrf, T> for U
727where
728    T: TimeScale + Copy,
729    U: RotationProvider<T> + TryOffset<T, Tt>,
730{
731    type Error = RotationError;
732
733    fn try_rotation(
734        &self,
735        _origin: Pef<Iers2010>,
736        _target: Itrf,
737        time: Time<T>,
738    ) -> Result<Rotation, Self::Error> {
739        self.pef_to_itrf(time, ReferenceSystem::Iers2010)
740    }
741}
742
743impl<T, U> TryRotation<Itrf, Pef<Iers2010>, T> for U
744where
745    T: TimeScale + Copy,
746    U: RotationProvider<T> + TryOffset<T, Tt>,
747{
748    type Error = RotationError;
749
750    fn try_rotation(
751        &self,
752        _origin: Itrf,
753        _target: Pef<Iers2010>,
754        time: Time<T>,
755    ) -> Result<Rotation, Self::Error> {
756        self.itrf_to_pef(time, ReferenceSystem::Iers2010)
757    }
758}
759
760// TOD <-> TEME
761
762impl<T, U> TryRotation<Tod<Iers1996>, Teme, T> for U
763where
764    T: TimeScale + Copy,
765    U: RotationProvider<T> + TryOffset<T, Tdb>,
766{
767    type Error = RotationError;
768
769    fn try_rotation(
770        &self,
771        _origin: Tod<Iers1996>,
772        _target: Teme,
773        time: Time<T>,
774    ) -> Result<Rotation, Self::Error> {
775        self.tod_to_teme(time)
776    }
777}
778
779impl<T, U> TryRotation<Teme, Tod<Iers1996>, T> for U
780where
781    T: TimeScale + Copy,
782    U: RotationProvider<T> + TryOffset<T, Tdb>,
783{
784    type Error = RotationError;
785
786    fn try_rotation(
787        &self,
788        _origin: Teme,
789        _target: Tod<Iers1996>,
790        time: Time<T>,
791    ) -> Result<Rotation, Self::Error> {
792        self.teme_to_tod(time)
793    }
794}
795
796impl<T, U> TryRotation<Tod<Iers2003>, Teme, T> for U
797where
798    T: TimeScale + Copy,
799    U: RotationProvider<T> + TryOffset<T, Tdb>,
800{
801    type Error = RotationError;
802
803    fn try_rotation(
804        &self,
805        _origin: Tod<Iers2003>,
806        _target: Teme,
807        time: Time<T>,
808    ) -> Result<Rotation, Self::Error> {
809        self.tod_to_teme(time)
810    }
811}
812
813impl<T, U> TryRotation<Teme, Tod<Iers2003>, T> for U
814where
815    T: TimeScale + Copy,
816    U: RotationProvider<T> + TryOffset<T, Tdb>,
817{
818    type Error = RotationError;
819
820    fn try_rotation(
821        &self,
822        _origin: Teme,
823        _target: Tod<Iers2003>,
824        time: Time<T>,
825    ) -> Result<Rotation, Self::Error> {
826        self.teme_to_tod(time)
827    }
828}
829
830impl<T, U> TryRotation<Tod<Iers2010>, Teme, T> for U
831where
832    T: TimeScale + Copy,
833    U: RotationProvider<T> + TryOffset<T, Tdb>,
834{
835    type Error = RotationError;
836
837    fn try_rotation(
838        &self,
839        _origin: Tod<Iers2010>,
840        _target: Teme,
841        time: Time<T>,
842    ) -> Result<Rotation, Self::Error> {
843        self.tod_to_teme(time)
844    }
845}
846
847impl<T, U> TryRotation<Teme, Tod<Iers2010>, T> for U
848where
849    T: TimeScale + Copy,
850    U: RotationProvider<T> + TryOffset<T, Tdb>,
851{
852    type Error = RotationError;
853
854    fn try_rotation(
855        &self,
856        _origin: Teme,
857        _target: Tod<Iers2010>,
858        time: Time<T>,
859    ) -> Result<Rotation, Self::Error> {
860        self.teme_to_tod(time)
861    }
862}
863
864// Composed Rotations
865
866macro_rules! impl_composed {
867    ($($origin:ty => $target:ty: [$($via:expr),+]),* $(,)?) => {
868        $(
869            impl<T, U> TryRotation<$origin, $target, T> for U
870            where
871                T: TimeScale + Copy,
872                U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Tdb> + TryOffset<T, Ut1>,
873            {
874                type Error = RotationError;
875
876                fn try_rotation(
877                    &self,
878                    origin: $origin,
879                    target: $target,
880                    time: Time<T>,
881                ) -> Result<Rotation, Self::Error> {
882                    (origin, $($via),+, target).try_composed_rotation(self, time)
883                }
884            }
885        )*
886    };
887}
888
889impl_composed!(
890    // J2000 composed rotations
891    J2000 => Cirf: [Icrf],
892    J2000 => Tirf: [Icrf, Cirf],
893    J2000 => Itrf: [Icrf, Cirf, Tirf],
894    J2000 => Iau<DynOrigin>: [Icrf],
895    J2000 => Tod<Iers1996>: [Mod(Iers1996)],
896    J2000 => Tod<Iers2003>: [Mod(Iers2003::default())],
897    J2000 => Tod<Iers2010>: [Mod(Iers2010)],
898    J2000 => Pef<Iers1996>: [Mod(Iers1996), Tod(Iers1996)],
899    J2000 => Pef<Iers2003>: [Mod(Iers2003::default()), Tod(Iers2003::default())],
900    J2000 => Pef<Iers2010>: [Mod(Iers2010), Tod(Iers2010)],
901    J2000 => Teme: [Mod(Iers1996), Tod(Iers1996)],
902    Cirf => J2000: [Icrf],
903    Tirf => J2000: [Cirf, Icrf],
904    Itrf => J2000: [Tirf, Cirf, Icrf],
905    Iau<DynOrigin> => J2000: [Icrf],
906    Tod<Iers1996> => J2000: [Mod(Iers1996)],
907    Tod<Iers2003> => J2000: [Mod(Iers2003::default())],
908    Tod<Iers2010> => J2000: [Mod(Iers2010)],
909    Pef<Iers1996> => J2000: [Tod(Iers1996), Mod(Iers1996)],
910    Pef<Iers2003> => J2000: [Tod(Iers2003::default()), Mod(Iers2003::default())],
911    Pef<Iers2010> => J2000: [Tod(Iers2010), Mod(Iers2010)],
912    Teme => J2000: [Tod(Iers1996), Mod(Iers1996)],
913
914    Cirf => Iau<DynOrigin>: [Icrf],
915    Cirf => Itrf: [Tirf],
916    Cirf => Mod<Iers1996>: [Icrf],
917    Cirf => Mod<Iers2003>: [Icrf],
918    Cirf => Mod<Iers2010>: [Icrf],
919    Cirf => Pef<Iers1996>: [Icrf, Mod(Iers1996), Tod(Iers1996)],
920    Cirf => Pef<Iers2003>: [Icrf, Mod(Iers2003::default()), Tod(Iers2003::default())],
921    Cirf => Pef<Iers2010>: [Icrf, Mod(Iers2010), Tod(Iers2010)],
922    Cirf => Teme: [Icrf, Mod(Iers1996), Tod(Iers1996)],
923    Cirf => Tod<Iers1996>: [Icrf, Mod(Iers1996)],
924    Cirf => Tod<Iers2003>: [Icrf, Mod(Iers2003::default())],
925    Cirf => Tod<Iers2010>: [Icrf, Mod(Iers2010)],
926    Iau<DynOrigin> => Cirf: [Icrf],
927    Iau<DynOrigin> => Itrf: [Icrf, Cirf, Tirf],
928    Iau<DynOrigin> => Tirf: [Icrf, Cirf],
929    Iau<DynOrigin> => Mod<Iers1996>: [Icrf],
930    Iau<DynOrigin> => Mod<Iers2003>: [Icrf],
931    Iau<DynOrigin> => Mod<Iers2010>: [Icrf],
932    Iau<DynOrigin> => Tod<Iers1996>: [Icrf, Mod(Iers1996)],
933    Iau<DynOrigin> => Tod<Iers2003>: [Icrf, Mod(Iers2003::default())],
934    Iau<DynOrigin> => Tod<Iers2010>: [Icrf, Mod(Iers2010)],
935    Iau<DynOrigin> => Pef<Iers1996>: [Icrf, Mod(Iers1996), Tod(Iers1996)],
936    Iau<DynOrigin> => Pef<Iers2003>: [Icrf, Mod(Iers2003::default()), Tod(Iers2003::default())],
937    Iau<DynOrigin> => Pef<Iers2010>: [Icrf, Mod(Iers2010), Tod(Iers2010)],
938    Iau<DynOrigin> => Teme: [Icrf, Mod(Iers1996), Tod(Iers1996)],
939    Icrf => Pef<Iers1996>: [Mod(Iers1996), Tod(Iers1996)],
940    Icrf => Pef<Iers2003>: [Mod(Iers2003::default()), Tod(Iers2003::default())],
941    Icrf => Pef<Iers2010>: [Mod(Iers2010), Tod(Iers2010)],
942    Icrf => Teme: [Mod(Iers1996), Tod(Iers1996)],
943    Icrf => Tirf: [Cirf],
944    Icrf => Tod<Iers1996>: [Mod(Iers1996)],
945    Icrf => Tod<Iers2003>: [Mod(Iers2003::default())],
946    Icrf => Tod<Iers2010>: [Mod(Iers2010)],
947    Itrf => Cirf: [Tirf],
948    Itrf => Iau<DynOrigin>: [Tirf, Cirf, Icrf],
949    Itrf => Mod<Iers1996>: [Pef(Iers1996), Tod(Iers1996)],
950    Itrf => Mod<Iers2003>: [Pef(Iers2003::default()), Tod(Iers2003::default())],
951    Itrf => Mod<Iers2010>: [Pef(Iers2010), Tod(Iers2010)],
952    Itrf => Tod<Iers1996>: [Pef(Iers1996)],
953    Itrf => Tod<Iers2003>: [Pef(Iers2003::default())],
954    Itrf => Tod<Iers2010>: [Pef(Iers2010)],
955    Itrf => Teme: [Pef(Iers1996), Tod(Iers1996)],
956    Mod<Iers1996> => Cirf: [Icrf],
957    Mod<Iers2003> => Cirf: [Icrf],
958    Mod<Iers2010> => Cirf: [Icrf],
959    Mod<Iers1996> => Tirf: [Icrf, Cirf],
960    Mod<Iers2003> => Tirf: [Icrf, Cirf],
961    Mod<Iers2010> => Tirf: [Icrf, Cirf],
962    Mod<Iers1996> => Itrf: [Tod(Iers1996), Pef(Iers1996)],
963    Mod<Iers2003> => Itrf: [Tod(Iers2003::default()), Pef(Iers2003::default())],
964    Mod<Iers2010> => Itrf: [Tod(Iers2010), Pef(Iers2010)],
965    Mod<Iers1996> => Iau<DynOrigin>: [Icrf],
966    Mod<Iers2003> => Iau<DynOrigin>: [Icrf],
967    Mod<Iers2010> => Iau<DynOrigin>: [Icrf],
968    Mod<Iers1996> => Pef<Iers1996>: [Tod(Iers1996)],
969    Mod<Iers2003> => Pef<Iers2003>: [Tod(Iers2003::default())],
970    Mod<Iers2010> => Pef<Iers2010>: [Tod(Iers2010)],
971    Mod<Iers1996> => Teme: [Tod(Iers1996)],
972    Mod<Iers2003> => Teme: [Tod(Iers2003::default())],
973    Mod<Iers2010> => Teme: [Tod(Iers2010)],
974    Pef<Iers1996> => Cirf: [Tod(Iers1996), Mod(Iers1996), Icrf],
975    Pef<Iers2003> => Cirf: [Tod(Iers2003::default()), Mod(Iers2003::default()), Icrf],
976    Pef<Iers2010> => Cirf: [Tod(Iers2010), Mod(Iers2010), Icrf],
977    Pef<Iers1996> => Icrf: [Tod(Iers1996), Mod(Iers1996)],
978    Pef<Iers2003> => Icrf: [Tod(Iers2003::default()), Mod(Iers2003::default())],
979    Pef<Iers2010> => Icrf: [Tod(Iers2010), Mod(Iers2010)],
980    Pef<Iers1996> => Tirf: [Itrf],
981    Pef<Iers2003> => Tirf: [Itrf],
982    Pef<Iers2010> => Tirf: [Itrf],
983    Pef<Iers1996> => Iau<DynOrigin>: [Tod(Iers1996), Mod(Iers1996), Icrf],
984    Pef<Iers2003> => Iau<DynOrigin>: [Tod(Iers2003::default()), Mod(Iers2003::default()), Icrf],
985    Pef<Iers2010> => Iau<DynOrigin>: [Tod(Iers2010), Mod(Iers2010), Icrf],
986    Pef<Iers1996> => Mod<Iers1996>: [Tod(Iers1996)],
987    Pef<Iers2003> => Mod<Iers2003>: [Tod(Iers2003::default())],
988    Pef<Iers2010> => Mod<Iers2010>: [Tod(Iers2010)],
989    Teme => Cirf: [Tod(Iers1996), Mod(Iers1996), Icrf],
990    Teme => Icrf: [Tod(Iers1996), Mod(Iers1996)],
991    Teme => Tirf: [Tod(Iers1996), Mod(Iers1996), Icrf, Cirf],
992    Teme => Itrf: [Tod(Iers1996), Pef(Iers1996)],
993    Teme => Iau<DynOrigin>: [Tod(Iers1996), Mod(Iers1996), Icrf],
994    Teme => Mod<Iers1996>: [Tod(Iers1996)],
995    Teme => Mod<Iers2003>: [Tod(Iers2003::default())],
996    Teme => Mod<Iers2010>: [Tod(Iers2010)],
997    Teme => Pef<Iers1996>: [Tod(Iers1996)],
998    Teme => Pef<Iers2003>: [Tod(Iers2003::default())],
999    Teme => Pef<Iers2010>: [Tod(Iers2010)],
1000    Tirf => Iau<DynOrigin>: [Cirf, Icrf],
1001    Tirf => Icrf: [Cirf],
1002    Tirf => Mod<Iers1996>: [Cirf, Icrf],
1003    Tirf => Mod<Iers2003>: [Cirf, Icrf],
1004    Tirf => Mod<Iers2010>: [Cirf, Icrf],
1005    Tirf => Pef<Iers1996>: [Itrf],
1006    Tirf => Pef<Iers2003>: [Itrf],
1007    Tirf => Pef<Iers2010>: [Itrf],
1008    Tirf => Teme: [Cirf, Icrf, Mod(Iers1996), Tod(Iers1996)],
1009    Tirf => Tod<Iers1996>: [Cirf, Icrf, Mod(Iers1996)],
1010    Tirf => Tod<Iers2003>: [Cirf, Icrf, Mod(Iers2003::default())],
1011    Tirf => Tod<Iers2010>: [Cirf, Icrf, Mod(Iers2010)],
1012    Tod<Iers1996> => Cirf: [Mod(Iers1996), Icrf],
1013    Tod<Iers2003> => Cirf: [Mod(Iers2003::default()), Icrf],
1014    Tod<Iers2010> => Cirf: [Mod(Iers2010), Icrf],
1015    Tod<Iers1996> => Icrf: [Mod(Iers1996)],
1016    Tod<Iers2003> => Icrf: [Mod(Iers2003::default())],
1017    Tod<Iers2010> => Icrf: [Mod(Iers2010)],
1018    Tod<Iers1996> => Tirf: [Mod(Iers1996), Icrf, Cirf],
1019    Tod<Iers2003> => Tirf: [Mod(Iers2003::default()), Icrf, Cirf],
1020    Tod<Iers2010> => Tirf: [Mod(Iers2010), Icrf, Cirf],
1021    Tod<Iers1996> => Itrf: [Pef(Iers1996)],
1022    Tod<Iers2003> => Itrf: [Pef(Iers2003::default())],
1023    Tod<Iers2010> => Itrf: [Pef(Iers2010)],
1024    Tod<Iers1996> => Iau<DynOrigin>: [Mod(Iers1996), Icrf],
1025    Tod<Iers2003> => Iau<DynOrigin>: [Mod(Iers2003::default()), Icrf],
1026    Tod<Iers2010> => Iau<DynOrigin>: [Mod(Iers2010), Icrf],
1027    Pef<Iers1996> => Teme: [Tod(Iers1996)],
1028    Pef<Iers2003> => Teme: [Tod(Iers2003::default())],
1029    Pef<Iers2010> => Teme: [Tod(Iers2010)],
1030);
1031
1032// Dynamic
1033
1034impl<T, U> TryRotation<DynFrame, DynFrame, T> for U
1035where
1036    T: TimeScale + Copy,
1037    U: RotationProvider<T> + TryOffset<T, Tt> + TryOffset<T, Tdb> + TryOffset<T, Ut1>,
1038{
1039    type Error = DynRotationError;
1040
1041    fn try_rotation(
1042        &self,
1043        origin: DynFrame,
1044        target: DynFrame,
1045        time: Time<T>,
1046    ) -> Result<Rotation, Self::Error> {
1047        match (origin, target) {
1048            (DynFrame::Icrf, DynFrame::Cirf) => Ok(self.try_rotation(Icrf, Cirf, time)?),
1049            (DynFrame::Icrf, DynFrame::Tirf) => Ok(self.try_rotation(Icrf, Tirf, time)?),
1050            (DynFrame::Icrf, DynFrame::Itrf) => Ok(self.try_rotation(Icrf, Itrf, time)?),
1051            (DynFrame::Icrf, DynFrame::Iau(body)) => {
1052                Ok(self.try_rotation(Icrf, Iau::try_new(body)?, time)?)
1053            }
1054            (DynFrame::Icrf, DynFrame::Mod(sys)) => match sys {
1055                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Icrf, Mod(Iers1996), time)?),
1056                ReferenceSystem::Iers2003(iau2000_model) => {
1057                    Ok(self.try_rotation(Icrf, Mod(Iers2003(iau2000_model)), time)?)
1058                }
1059                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Icrf, Mod(Iers2010), time)?),
1060            },
1061            (DynFrame::Icrf, DynFrame::Tod(sys)) => match sys {
1062                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Icrf, Tod(Iers1996), time)?),
1063                ReferenceSystem::Iers2003(iau2000_model) => {
1064                    Ok(self.try_rotation(Icrf, Tod(Iers2003(iau2000_model)), time)?)
1065                }
1066                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Icrf, Tod(Iers2010), time)?),
1067            },
1068            (DynFrame::Icrf, DynFrame::Pef(sys)) => match sys {
1069                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Icrf, Pef(Iers1996), time)?),
1070                ReferenceSystem::Iers2003(iau2000_model) => {
1071                    Ok(self.try_rotation(Icrf, Pef(Iers2003(iau2000_model)), time)?)
1072                }
1073                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Icrf, Pef(Iers2010), time)?),
1074            },
1075            (DynFrame::Icrf, DynFrame::Teme) => Ok(self.try_rotation(Icrf, Teme, time)?),
1076            (DynFrame::Icrf, DynFrame::J2000) => Ok(self.try_rotation(Icrf, J2000, time)?),
1077            (DynFrame::J2000, DynFrame::Icrf) => Ok(self.try_rotation(J2000, Icrf, time)?),
1078            (DynFrame::J2000, DynFrame::Cirf) => Ok(self.try_rotation(J2000, Cirf, time)?),
1079            (DynFrame::J2000, DynFrame::Tirf) => Ok(self.try_rotation(J2000, Tirf, time)?),
1080            (DynFrame::J2000, DynFrame::Itrf) => Ok(self.try_rotation(J2000, Itrf, time)?),
1081            (DynFrame::J2000, DynFrame::Iau(body)) => {
1082                Ok(self.try_rotation(J2000, Iau::try_new(body)?, time)?)
1083            }
1084            (DynFrame::J2000, DynFrame::Mod(sys)) => match sys {
1085                ReferenceSystem::Iers1996 => Ok(self.try_rotation(J2000, Mod(Iers1996), time)?),
1086                ReferenceSystem::Iers2003(iau2000_model) => {
1087                    Ok(self.try_rotation(J2000, Mod(Iers2003(iau2000_model)), time)?)
1088                }
1089                ReferenceSystem::Iers2010 => Ok(self.try_rotation(J2000, Mod(Iers2010), time)?),
1090            },
1091            (DynFrame::J2000, DynFrame::Tod(sys)) => match sys {
1092                ReferenceSystem::Iers1996 => Ok(self.try_rotation(J2000, Tod(Iers1996), time)?),
1093                ReferenceSystem::Iers2003(iau2000_model) => {
1094                    Ok(self.try_rotation(J2000, Tod(Iers2003(iau2000_model)), time)?)
1095                }
1096                ReferenceSystem::Iers2010 => Ok(self.try_rotation(J2000, Tod(Iers2010), time)?),
1097            },
1098            (DynFrame::J2000, DynFrame::Pef(sys)) => match sys {
1099                ReferenceSystem::Iers1996 => Ok(self.try_rotation(J2000, Pef(Iers1996), time)?),
1100                ReferenceSystem::Iers2003(iau2000_model) => {
1101                    Ok(self.try_rotation(J2000, Pef(Iers2003(iau2000_model)), time)?)
1102                }
1103                ReferenceSystem::Iers2010 => Ok(self.try_rotation(J2000, Pef(Iers2010), time)?),
1104            },
1105            (DynFrame::J2000, DynFrame::Teme) => Ok(self.try_rotation(J2000, Teme, time)?),
1106            (DynFrame::Cirf, DynFrame::Icrf) => Ok(self.try_rotation(Cirf, Icrf, time)?),
1107            (DynFrame::Cirf, DynFrame::Tirf) => Ok(self.try_rotation(Cirf, Tirf, time)?),
1108            (DynFrame::Cirf, DynFrame::Itrf) => Ok(self.try_rotation(Cirf, Itrf, time)?),
1109            (DynFrame::Cirf, DynFrame::Iau(body)) => {
1110                Ok(self.try_rotation(Cirf, Iau::try_new(body)?, time)?)
1111            }
1112            (DynFrame::Cirf, DynFrame::Mod(sys)) => match sys {
1113                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Cirf, Mod(Iers1996), time)?),
1114                ReferenceSystem::Iers2003(iau2000_model) => {
1115                    Ok(self.try_rotation(Cirf, Mod(Iers2003(iau2000_model)), time)?)
1116                }
1117                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Cirf, Mod(Iers2010), time)?),
1118            },
1119            (DynFrame::Cirf, DynFrame::Tod(sys)) => match sys {
1120                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Cirf, Tod(Iers1996), time)?),
1121                ReferenceSystem::Iers2003(iau2000_model) => {
1122                    Ok(self.try_rotation(Cirf, Tod(Iers2003(iau2000_model)), time)?)
1123                }
1124                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Cirf, Tod(Iers2010), time)?),
1125            },
1126            (DynFrame::Cirf, DynFrame::Pef(sys)) => match sys {
1127                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Cirf, Pef(Iers1996), time)?),
1128                ReferenceSystem::Iers2003(iau2000_model) => {
1129                    Ok(self.try_rotation(Cirf, Pef(Iers2003(iau2000_model)), time)?)
1130                }
1131                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Cirf, Pef(Iers2010), time)?),
1132            },
1133            (DynFrame::Cirf, DynFrame::Teme) => Ok(self.try_rotation(Cirf, Teme, time)?),
1134            (DynFrame::Cirf, DynFrame::J2000) => Ok(self.try_rotation(Cirf, J2000, time)?),
1135            (DynFrame::Tirf, DynFrame::Icrf) => Ok(self.try_rotation(Tirf, Icrf, time)?),
1136            (DynFrame::Tirf, DynFrame::Cirf) => Ok(self.try_rotation(Tirf, Cirf, time)?),
1137            (DynFrame::Tirf, DynFrame::Itrf) => Ok(self.try_rotation(Tirf, Itrf, time)?),
1138            (DynFrame::Tirf, DynFrame::Iau(body)) => {
1139                Ok(self.try_rotation(Tirf, Iau::try_new(body)?, time)?)
1140            }
1141            (DynFrame::Tirf, DynFrame::Mod(sys)) => match sys {
1142                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tirf, Mod(Iers1996), time)?),
1143                ReferenceSystem::Iers2003(iau2000_model) => {
1144                    Ok(self.try_rotation(Tirf, Mod(Iers2003(iau2000_model)), time)?)
1145                }
1146                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tirf, Mod(Iers2010), time)?),
1147            },
1148            (DynFrame::Tirf, DynFrame::Tod(sys)) => match sys {
1149                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tirf, Tod(Iers1996), time)?),
1150                ReferenceSystem::Iers2003(iau2000_model) => {
1151                    Ok(self.try_rotation(Tirf, Tod(Iers2003(iau2000_model)), time)?)
1152                }
1153                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tirf, Tod(Iers2010), time)?),
1154            },
1155            (DynFrame::Tirf, DynFrame::Pef(sys)) => match sys {
1156                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tirf, Pef(Iers1996), time)?),
1157                ReferenceSystem::Iers2003(iau2000_model) => {
1158                    Ok(self.try_rotation(Tirf, Pef(Iers2003(iau2000_model)), time)?)
1159                }
1160                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tirf, Pef(Iers2010), time)?),
1161            },
1162            (DynFrame::Tirf, DynFrame::Teme) => Ok(self.try_rotation(Tirf, Teme, time)?),
1163            (DynFrame::Tirf, DynFrame::J2000) => Ok(self.try_rotation(Tirf, J2000, time)?),
1164            (DynFrame::Itrf, DynFrame::Icrf) => Ok(self.try_rotation(Itrf, Icrf, time)?),
1165            (DynFrame::Itrf, DynFrame::Cirf) => Ok(self.try_rotation(Itrf, Cirf, time)?),
1166            (DynFrame::Itrf, DynFrame::Tirf) => Ok(self.try_rotation(Itrf, Tirf, time)?),
1167            (DynFrame::Itrf, DynFrame::Iau(body)) => {
1168                Ok(self.try_rotation(Itrf, Iau::try_new(body)?, time)?)
1169            }
1170            (DynFrame::Itrf, DynFrame::Mod(sys)) => match sys {
1171                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Itrf, Mod(Iers1996), time)?),
1172                ReferenceSystem::Iers2003(iau2000_model) => {
1173                    Ok(self.try_rotation(Itrf, Mod(Iers2003(iau2000_model)), time)?)
1174                }
1175                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Itrf, Mod(Iers2010), time)?),
1176            },
1177            (DynFrame::Itrf, DynFrame::Tod(sys)) => match sys {
1178                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Itrf, Tod(Iers1996), time)?),
1179                ReferenceSystem::Iers2003(iau2000_model) => {
1180                    Ok(self.try_rotation(Itrf, Tod(Iers2003(iau2000_model)), time)?)
1181                }
1182                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Itrf, Tod(Iers2010), time)?),
1183            },
1184            (DynFrame::Itrf, DynFrame::Pef(sys)) => match sys {
1185                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Itrf, Pef(Iers1996), time)?),
1186                ReferenceSystem::Iers2003(iau2000_model) => {
1187                    Ok(self.try_rotation(Itrf, Pef(Iers2003(iau2000_model)), time)?)
1188                }
1189                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Itrf, Pef(Iers2010), time)?),
1190            },
1191            (DynFrame::Itrf, DynFrame::Teme) => Ok(self.try_rotation(Itrf, Teme, time)?),
1192            (DynFrame::Itrf, DynFrame::J2000) => Ok(self.try_rotation(Itrf, J2000, time)?),
1193            (DynFrame::Iau(body), DynFrame::Icrf) => {
1194                Ok(self.try_rotation(Iau::try_new(body)?, Icrf, time)?)
1195            }
1196            (DynFrame::Iau(body), DynFrame::Cirf) => {
1197                Ok(self.try_rotation(Iau::try_new(body)?, Cirf, time)?)
1198            }
1199            (DynFrame::Iau(body), DynFrame::Tirf) => {
1200                Ok(self.try_rotation(Iau::try_new(body)?, Tirf, time)?)
1201            }
1202            (DynFrame::Iau(body), DynFrame::Itrf) => {
1203                Ok(self.try_rotation(Iau::try_new(body)?, Itrf, time)?)
1204            }
1205            (DynFrame::Iau(body), DynFrame::Mod(sys)) => match sys {
1206                ReferenceSystem::Iers1996 => {
1207                    Ok(self.try_rotation(Iau::try_new(body)?, Mod(Iers1996), time)?)
1208                }
1209                ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1210                    Iau::try_new(body)?,
1211                    Mod(Iers2003(iau2000_model)),
1212                    time,
1213                )?),
1214                ReferenceSystem::Iers2010 => {
1215                    Ok(self.try_rotation(Iau::try_new(body)?, Mod(Iers2010), time)?)
1216                }
1217            },
1218            (DynFrame::Iau(body), DynFrame::Tod(sys)) => match sys {
1219                ReferenceSystem::Iers1996 => {
1220                    Ok(self.try_rotation(Iau::try_new(body)?, Tod(Iers1996), time)?)
1221                }
1222                ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1223                    Iau::try_new(body)?,
1224                    Tod(Iers2003(iau2000_model)),
1225                    time,
1226                )?),
1227                ReferenceSystem::Iers2010 => {
1228                    Ok(self.try_rotation(Iau::try_new(body)?, Tod(Iers2010), time)?)
1229                }
1230            },
1231            (DynFrame::Iau(body), DynFrame::Pef(sys)) => match sys {
1232                ReferenceSystem::Iers1996 => {
1233                    Ok(self.try_rotation(Iau::try_new(body)?, Pef(Iers1996), time)?)
1234                }
1235                ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1236                    Iau::try_new(body)?,
1237                    Pef(Iers2003(iau2000_model)),
1238                    time,
1239                )?),
1240                ReferenceSystem::Iers2010 => {
1241                    Ok(self.try_rotation(Iau::try_new(body)?, Pef(Iers2010), time)?)
1242                }
1243            },
1244            (DynFrame::Iau(body), DynFrame::Teme) => {
1245                Ok(self.try_rotation(Iau::try_new(body)?, Teme, time)?)
1246            }
1247            (DynFrame::Iau(body), DynFrame::J2000) => {
1248                Ok(self.try_rotation(Iau::try_new(body)?, J2000, time)?)
1249            }
1250            (DynFrame::Mod(sys), DynFrame::Icrf) => match sys {
1251                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Mod(Iers1996), Icrf, time)?),
1252                ReferenceSystem::Iers2003(iau2000_model) => {
1253                    Ok(self.try_rotation(Mod(Iers2003(iau2000_model)), Icrf, time)?)
1254                }
1255                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Mod(Iers2010), Icrf, time)?),
1256            },
1257            (DynFrame::Mod(sys), DynFrame::Cirf) => match sys {
1258                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Mod(Iers1996), Cirf, time)?),
1259                ReferenceSystem::Iers2003(iau2000_model) => {
1260                    Ok(self.try_rotation(Mod(Iers2003(iau2000_model)), Cirf, time)?)
1261                }
1262                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Mod(Iers2010), Cirf, time)?),
1263            },
1264            (DynFrame::Mod(sys), DynFrame::Tirf) => match sys {
1265                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Mod(Iers1996), Tirf, time)?),
1266                ReferenceSystem::Iers2003(iau2000_model) => {
1267                    Ok(self.try_rotation(Mod(Iers2003(iau2000_model)), Tirf, time)?)
1268                }
1269                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Mod(Iers2010), Tirf, time)?),
1270            },
1271            (DynFrame::Mod(sys), DynFrame::Itrf) => match sys {
1272                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Mod(Iers1996), Itrf, time)?),
1273                ReferenceSystem::Iers2003(iau2000_model) => {
1274                    Ok(self.try_rotation(Mod(Iers2003(iau2000_model)), Itrf, time)?)
1275                }
1276                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Mod(Iers2010), Itrf, time)?),
1277            },
1278            (DynFrame::Mod(sys), DynFrame::Iau(body)) => match sys {
1279                ReferenceSystem::Iers1996 => {
1280                    Ok(self.try_rotation(Mod(Iers1996), Iau::try_new(body)?, time)?)
1281                }
1282                ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1283                    Mod(Iers2003(iau2000_model)),
1284                    Iau::try_new(body)?,
1285                    time,
1286                )?),
1287                ReferenceSystem::Iers2010 => {
1288                    Ok(self.try_rotation(Mod(Iers2010), Iau::try_new(body)?, time)?)
1289                }
1290            },
1291            (DynFrame::Mod(sys1), DynFrame::Tod(sys2)) => {
1292                if sys1 != sys2 {
1293                    return Err(DynRotationError::IncompatibleReferenceSystems);
1294                }
1295                match sys1 {
1296                    ReferenceSystem::Iers1996 => {
1297                        Ok(self.try_rotation(Mod(Iers1996), Tod(Iers1996), time)?)
1298                    }
1299                    ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1300                        Mod(Iers2003(iau2000_model)),
1301                        Tod(Iers2003(iau2000_model)),
1302                        time,
1303                    )?),
1304                    ReferenceSystem::Iers2010 => {
1305                        Ok(self.try_rotation(Mod(Iers2010), Tod(Iers2010), time)?)
1306                    }
1307                }
1308            }
1309            (DynFrame::Mod(sys1), DynFrame::Pef(sys2)) => {
1310                if sys1 != sys2 {
1311                    return Err(DynRotationError::IncompatibleReferenceSystems);
1312                }
1313                match sys1 {
1314                    ReferenceSystem::Iers1996 => {
1315                        Ok(self.try_rotation(Mod(Iers1996), Pef(Iers1996), time)?)
1316                    }
1317                    ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1318                        Mod(Iers2003(iau2000_model)),
1319                        Pef(Iers2003(iau2000_model)),
1320                        time,
1321                    )?),
1322                    ReferenceSystem::Iers2010 => {
1323                        Ok(self.try_rotation(Mod(Iers2010), Pef(Iers2010), time)?)
1324                    }
1325                }
1326            }
1327            (DynFrame::Mod(sys), DynFrame::Teme) => match sys {
1328                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Mod(Iers1996), Teme, time)?),
1329                ReferenceSystem::Iers2003(iau2000_model) => {
1330                    Ok(self.try_rotation(Mod(Iers2003(iau2000_model)), Teme, time)?)
1331                }
1332                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Mod(Iers2010), Teme, time)?),
1333            },
1334            (DynFrame::Mod(sys), DynFrame::J2000) => match sys {
1335                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Mod(Iers1996), J2000, time)?),
1336                ReferenceSystem::Iers2003(iau2000_model) => {
1337                    Ok(self.try_rotation(Mod(Iers2003(iau2000_model)), J2000, time)?)
1338                }
1339                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Mod(Iers2010), J2000, time)?),
1340            },
1341            (DynFrame::Tod(sys), DynFrame::Icrf) => match sys {
1342                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tod(Iers1996), Icrf, time)?),
1343                ReferenceSystem::Iers2003(iau2000_model) => {
1344                    Ok(self.try_rotation(Tod(Iers2003(iau2000_model)), Icrf, time)?)
1345                }
1346                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tod(Iers2010), Icrf, time)?),
1347            },
1348            (DynFrame::Tod(sys), DynFrame::Cirf) => match sys {
1349                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tod(Iers1996), Cirf, time)?),
1350                ReferenceSystem::Iers2003(iau2000_model) => {
1351                    Ok(self.try_rotation(Tod(Iers2003(iau2000_model)), Cirf, time)?)
1352                }
1353                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tod(Iers2010), Cirf, time)?),
1354            },
1355            (DynFrame::Tod(sys), DynFrame::Tirf) => match sys {
1356                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tod(Iers1996), Tirf, time)?),
1357                ReferenceSystem::Iers2003(iau2000_model) => {
1358                    Ok(self.try_rotation(Tod(Iers2003(iau2000_model)), Tirf, time)?)
1359                }
1360                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tod(Iers2010), Tirf, time)?),
1361            },
1362            (DynFrame::Tod(sys), DynFrame::Itrf) => match sys {
1363                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tod(Iers1996), Itrf, time)?),
1364                ReferenceSystem::Iers2003(iau2000_model) => {
1365                    Ok(self.try_rotation(Tod(Iers2003(iau2000_model)), Itrf, time)?)
1366                }
1367                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tod(Iers2010), Itrf, time)?),
1368            },
1369            (DynFrame::Tod(sys), DynFrame::Iau(body)) => match sys {
1370                ReferenceSystem::Iers1996 => {
1371                    Ok(self.try_rotation(Tod(Iers1996), Iau::try_new(body)?, time)?)
1372                }
1373                ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1374                    Tod(Iers2003(iau2000_model)),
1375                    Iau::try_new(body)?,
1376                    time,
1377                )?),
1378                ReferenceSystem::Iers2010 => {
1379                    Ok(self.try_rotation(Tod(Iers2010), Iau::try_new(body)?, time)?)
1380                }
1381            },
1382            (DynFrame::Tod(sys1), DynFrame::Mod(sys2)) => {
1383                if sys1 != sys2 {
1384                    return Err(DynRotationError::IncompatibleReferenceSystems);
1385                }
1386                match sys1 {
1387                    ReferenceSystem::Iers1996 => {
1388                        Ok(self.try_rotation(Tod(Iers1996), Mod(Iers1996), time)?)
1389                    }
1390                    ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1391                        Tod(Iers2003(iau2000_model)),
1392                        Mod(Iers2003(iau2000_model)),
1393                        time,
1394                    )?),
1395                    ReferenceSystem::Iers2010 => {
1396                        Ok(self.try_rotation(Tod(Iers2010), Mod(Iers2010), time)?)
1397                    }
1398                }
1399            }
1400            (DynFrame::Tod(sys1), DynFrame::Pef(sys2)) => {
1401                if sys1 != sys2 {
1402                    return Err(DynRotationError::IncompatibleReferenceSystems);
1403                }
1404                match sys1 {
1405                    ReferenceSystem::Iers1996 => {
1406                        Ok(self.try_rotation(Tod(Iers1996), Pef(Iers1996), time)?)
1407                    }
1408                    ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1409                        Tod(Iers2003(iau2000_model)),
1410                        Pef(Iers2003(iau2000_model)),
1411                        time,
1412                    )?),
1413                    ReferenceSystem::Iers2010 => {
1414                        Ok(self.try_rotation(Tod(Iers2010), Pef(Iers2010), time)?)
1415                    }
1416                }
1417            }
1418            (DynFrame::Tod(sys), DynFrame::Teme) => match sys {
1419                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tod(Iers1996), Teme, time)?),
1420                ReferenceSystem::Iers2003(iau2000_model) => {
1421                    Ok(self.try_rotation(Tod(Iers2003(iau2000_model)), Teme, time)?)
1422                }
1423                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tod(Iers2010), Teme, time)?),
1424            },
1425            (DynFrame::Tod(sys), DynFrame::J2000) => match sys {
1426                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Tod(Iers1996), J2000, time)?),
1427                ReferenceSystem::Iers2003(iau2000_model) => {
1428                    Ok(self.try_rotation(Tod(Iers2003(iau2000_model)), J2000, time)?)
1429                }
1430                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Tod(Iers2010), J2000, time)?),
1431            },
1432            (DynFrame::Pef(sys), DynFrame::Icrf) => match sys {
1433                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Pef(Iers1996), Icrf, time)?),
1434                ReferenceSystem::Iers2003(iau2000_model) => {
1435                    Ok(self.try_rotation(Pef(Iers2003(iau2000_model)), Icrf, time)?)
1436                }
1437                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Pef(Iers2010), Icrf, time)?),
1438            },
1439            (DynFrame::Pef(sys), DynFrame::Cirf) => match sys {
1440                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Pef(Iers1996), Cirf, time)?),
1441                ReferenceSystem::Iers2003(iau2000_model) => {
1442                    Ok(self.try_rotation(Pef(Iers2003(iau2000_model)), Cirf, time)?)
1443                }
1444                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Pef(Iers2010), Cirf, time)?),
1445            },
1446            (DynFrame::Pef(sys), DynFrame::Tirf) => match sys {
1447                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Pef(Iers1996), Tirf, time)?),
1448                ReferenceSystem::Iers2003(iau2000_model) => {
1449                    Ok(self.try_rotation(Pef(Iers2003(iau2000_model)), Tirf, time)?)
1450                }
1451                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Pef(Iers2010), Tirf, time)?),
1452            },
1453            (DynFrame::Pef(sys), DynFrame::Itrf) => match sys {
1454                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Pef(Iers1996), Itrf, time)?),
1455                ReferenceSystem::Iers2003(iau2000_model) => {
1456                    Ok(self.try_rotation(Pef(Iers2003(iau2000_model)), Itrf, time)?)
1457                }
1458                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Pef(Iers2010), Itrf, time)?),
1459            },
1460            (DynFrame::Pef(sys), DynFrame::Iau(body)) => match sys {
1461                ReferenceSystem::Iers1996 => {
1462                    Ok(self.try_rotation(Pef(Iers1996), Iau::try_new(body)?, time)?)
1463                }
1464                ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1465                    Pef(Iers2003(iau2000_model)),
1466                    Iau::try_new(body)?,
1467                    time,
1468                )?),
1469                ReferenceSystem::Iers2010 => {
1470                    Ok(self.try_rotation(Pef(Iers2010), Iau::try_new(body)?, time)?)
1471                }
1472            },
1473            (DynFrame::Pef(sys1), DynFrame::Mod(sys2)) => {
1474                if sys1 != sys2 {
1475                    return Err(DynRotationError::IncompatibleReferenceSystems);
1476                }
1477                match sys1 {
1478                    ReferenceSystem::Iers1996 => {
1479                        Ok(self.try_rotation(Pef(Iers1996), Mod(Iers1996), time)?)
1480                    }
1481                    ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1482                        Pef(Iers2003(iau2000_model)),
1483                        Mod(Iers2003(iau2000_model)),
1484                        time,
1485                    )?),
1486                    ReferenceSystem::Iers2010 => {
1487                        Ok(self.try_rotation(Pef(Iers2010), Mod(Iers2010), time)?)
1488                    }
1489                }
1490            }
1491            (DynFrame::Pef(sys1), DynFrame::Tod(sys2)) => {
1492                if sys1 != sys2 {
1493                    return Err(DynRotationError::IncompatibleReferenceSystems);
1494                }
1495                match sys1 {
1496                    ReferenceSystem::Iers1996 => {
1497                        Ok(self.try_rotation(Pef(Iers1996), Tod(Iers1996), time)?)
1498                    }
1499                    ReferenceSystem::Iers2003(iau2000_model) => Ok(self.try_rotation(
1500                        Pef(Iers2003(iau2000_model)),
1501                        Tod(Iers2003(iau2000_model)),
1502                        time,
1503                    )?),
1504                    ReferenceSystem::Iers2010 => {
1505                        Ok(self.try_rotation(Pef(Iers2010), Tod(Iers2010), time)?)
1506                    }
1507                }
1508            }
1509            (DynFrame::Pef(sys), DynFrame::Teme) => match sys {
1510                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Pef(Iers1996), Teme, time)?),
1511                ReferenceSystem::Iers2003(iau2000_model) => {
1512                    Ok(self.try_rotation(Pef(Iers2003(iau2000_model)), Teme, time)?)
1513                }
1514                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Pef(Iers2010), Teme, time)?),
1515            },
1516            (DynFrame::Pef(sys), DynFrame::J2000) => match sys {
1517                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Pef(Iers1996), J2000, time)?),
1518                ReferenceSystem::Iers2003(iau2000_model) => {
1519                    Ok(self.try_rotation(Pef(Iers2003(iau2000_model)), J2000, time)?)
1520                }
1521                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Pef(Iers2010), J2000, time)?),
1522            },
1523            (DynFrame::Teme, DynFrame::Icrf) => Ok(self.try_rotation(Teme, Icrf, time)?),
1524            (DynFrame::Teme, DynFrame::Cirf) => Ok(self.try_rotation(Teme, Cirf, time)?),
1525            (DynFrame::Teme, DynFrame::Tirf) => Ok(self.try_rotation(Teme, Tirf, time)?),
1526            (DynFrame::Teme, DynFrame::Itrf) => Ok(self.try_rotation(Teme, Itrf, time)?),
1527            (DynFrame::Teme, DynFrame::Iau(body)) => {
1528                Ok(self.try_rotation(Teme, Iau::try_new(body)?, time)?)
1529            }
1530            (DynFrame::Teme, DynFrame::Mod(sys)) => match sys {
1531                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Teme, Mod(Iers1996), time)?),
1532                ReferenceSystem::Iers2003(iau2000_model) => {
1533                    Ok(self.try_rotation(Teme, Mod(Iers2003(iau2000_model)), time)?)
1534                }
1535                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Teme, Mod(Iers2010), time)?),
1536            },
1537            (DynFrame::Teme, DynFrame::Tod(sys)) => match sys {
1538                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Teme, Tod(Iers1996), time)?),
1539                ReferenceSystem::Iers2003(iau2000_model) => {
1540                    Ok(self.try_rotation(Teme, Tod(Iers2003(iau2000_model)), time)?)
1541                }
1542                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Teme, Tod(Iers2010), time)?),
1543            },
1544            (DynFrame::Teme, DynFrame::Pef(sys)) => match sys {
1545                ReferenceSystem::Iers1996 => Ok(self.try_rotation(Teme, Pef(Iers1996), time)?),
1546                ReferenceSystem::Iers2003(iau2000_model) => {
1547                    Ok(self.try_rotation(Teme, Pef(Iers2003(iau2000_model)), time)?)
1548                }
1549                ReferenceSystem::Iers2010 => Ok(self.try_rotation(Teme, Pef(Iers2010), time)?),
1550            },
1551            (DynFrame::Teme, DynFrame::J2000) => Ok(self.try_rotation(Teme, J2000, time)?),
1552            (_, _) => Ok(Rotation::IDENTITY),
1553        }
1554    }
1555}