Skip to content

Commit

Permalink
Explanation
Browse files Browse the repository at this point in the history
  • Loading branch information
AngusGMorrison committed Nov 20, 2023
1 parent 66e92c4 commit 15a3ff1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions crates/lox_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub mod communications;
pub mod ephemeris;
pub mod errors;
pub mod frames;
pub mod marked_bodies;
pub mod time;
pub mod two_body;
pub mod types;
Expand Down
39 changes: 33 additions & 6 deletions crates/lox_core/src/marked_bodies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,25 @@
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*/

use crate::bodies::{Body, NaifId};
use std::marker::PhantomData;

/// Problem: different conventions define the same fundamental arguments differently for the same
/// bodies. For example, the mean longitude of the ascending node of the Moon is defined differently
/// in the IERS2003 and MHB2000 conventions. The set of traits defined in fundamental.rs is
/// IERS2003-only, but we don't want to define a new trait for each combination of conventions and
/// argument, which will quickly get out of hand and lead to long, convoluted method names to
/// avoid clashes when implemented on the same body. Nor do we want to define a new body for
/// each set of conventions – there are enough of them as it is.
///
/// Proposed solution: Following a recommendation in Rust for Rustaceans, we can define a marker type for
/// each convention, make the body generic over the marker, and implement the same trait for each
/// marker. The body remains zero-sized, its instances are constant, and there's no need to
/// namespace fundamental arguments trait declarations.
///
/// This is also clearer for consumers of the API, who no longer have to wonder why mod fundamental
/// provides only IERS03 fundamental args.
/// Marker types indicating the conventions followed by the body.
struct IERS2003;
struct MHB2000;
Expand Down Expand Up @@ -36,19 +53,29 @@ impl MeanLongitudeOfAscendingNode for Moon<MHB2000> {

/// And it's still possible to implement methods that don't care about the conventions
/// followed by the body.
impl Body for Moon<T> {
fn naif_id() -> i32 {
301
impl<T> Body for Moon<T> {
fn id(&self) -> NaifId {
NaifId(301)
}

fn name() -> &'static str {
fn name(&self) -> &'static str {
"Moon"
}
}

/// One disadvantage is that our ZSTs can no longer be used as types or instances interchangeably,
/// but, still being zero-sized, these objects are considered constant and can be defined as such.
const MOON_IERS2003: Moon<IERS2003> = Moon {
_convention: PhantomData,
};

const MOON_MHB2000: Moon<MHB2000> = Moon {
_convention: PhantomData,
};

fn example_usage() {
let iers2003_mean_long = Moon::<IERS2003>.mean_longitude_of_ascending_node();
let mhb2000_mean_long = Moon::<MHB2000>.mean_longitude_of_ascending_node();
let iers2003_mean_long = MOON_IERS2003.mean_longitude_of_ascending_node();
let mhb2000_mean_long = MOON_MHB2000.mean_longitude_of_ascending_node();
}

#[cfg(test)]
Expand Down

0 comments on commit 15a3ff1

Please sign in to comment.