Skip to main content

lox_frames/
traits.rs

1// SPDX-FileCopyrightText: 2025 Helge Eichhorn <git@helgeeichhorn.de>
2//
3// SPDX-License-Identifier: MPL-2.0
4
5use thiserror::Error;
6
7pub(crate) mod private {
8    /// Internal token to seal frame_id.
9    pub struct Internal;
10}
11
12/// A reference frame with a human-readable name and abbreviation.
13pub trait ReferenceFrame {
14    /// Returns the full name of the frame (e.g. "International Celestial Reference Frame").
15    fn name(&self) -> String;
16    /// Returns the abbreviated name (e.g. "ICRF").
17    fn abbreviation(&self) -> String;
18    #[doc(hidden)]
19    fn frame_id(&self, _: private::Internal) -> Option<usize> {
20        None
21    }
22}
23
24/// Returns the internal numeric frame identifier, if assigned.
25pub fn frame_id(frame: &impl ReferenceFrame) -> Option<usize> {
26    frame.frame_id(private::Internal)
27}
28
29/// Marker trait for quasi-inertial reference frames.
30pub trait QuasiInertial: ReferenceFrame {}
31
32/// The frame is not quasi-inertial.
33#[derive(Clone, Debug, Error, Eq, PartialEq)]
34#[error("{0} is not a quasi-inertial frame")]
35pub struct NonQuasiInertialFrameError(pub String);
36
37/// Fallible check for quasi-inertial frames (used by dynamic dispatch).
38pub trait TryQuasiInertial: ReferenceFrame {
39    /// Returns `Ok(())` if the frame is quasi-inertial.
40    fn try_quasi_inertial(&self) -> Result<(), NonQuasiInertialFrameError>;
41}
42
43impl<T: QuasiInertial> TryQuasiInertial for T {
44    fn try_quasi_inertial(&self) -> Result<(), NonQuasiInertialFrameError> {
45        Ok(())
46    }
47}
48
49/// Marker trait for body-fixed reference frames.
50pub trait BodyFixed: ReferenceFrame {}
51
52/// The frame is not body-fixed.
53#[derive(Clone, Debug, Error)]
54#[error("{0} is not a body-fixed frame")]
55pub struct NonBodyFixedFrameError(pub String);
56
57/// Fallible check for body-fixed frames (used by dynamic dispatch).
58pub trait TryBodyFixed: ReferenceFrame {
59    /// Returns `Ok(())` if the frame is body-fixed.
60    fn try_body_fixed(&self) -> Result<(), NonBodyFixedFrameError>;
61}
62
63impl<T: BodyFixed> TryBodyFixed for T {
64    fn try_body_fixed(&self) -> Result<(), NonBodyFixedFrameError> {
65        Ok(())
66    }
67}