keplerian_sim 0.7.3

A Keplerian orbit library
Documentation
macro_rules! trait_decl {
    ( $( $fname:ident $( / $_lname:ident )? $( : $arity:tt )? $( -> $ret:tt )? ),* $(,)? ) => {
        $(
            trait_decl!(@make fn $fname $( : $arity )? $( -> $ret )? );
        )*
    };

    (@make fn $fname:ident) => {
        fn $fname(self) -> Self;
    };

    (@make fn $fname:ident : 2) => {
        fn $fname(self, y: Self) -> Self;
    };

    (@make fn $fname:ident -> 2) => {
        fn $fname(self) -> (Self, Self);
    };
}

macro_rules! trait_impl {
    ( $( $fname:ident $( / $lname:ident )? $( : $arity:tt )? $( -> $ret:tt )? ),* $(,)? ) => {
        $(
            trait_impl!(@make fn $fname $( / $lname )? $( : $arity )? $( -> $ret )? );
        )*
    };

    (@make fn $fname:ident) => {
        fn $fname(self) -> Self {
            libm::$fname(self)
        }
    };

    (@make fn $fname:ident : 2) => {
        fn $fname(self, y: Self) -> Self {
            libm::$fname(self, y)
        }
    };

    (@make fn $fname:ident / $lname:ident) => {
        fn $fname(self) -> Self {
            libm::$lname(self)
        }
    };

    (@make fn $fname:ident / $lname:ident -> 2) => {
        fn $fname(self) -> (Self, Self) {
            libm::$lname(self)
        }
    };
}

#[allow(dead_code)]
pub(crate) trait F64Math: Sized {
    trait_decl!(
        abs,
        signum,
        copysign: 2,
        sin,
        cos,
        tan,
        sinh,
        cosh,
        tanh,
        asin,
        acos,
        atan,
        atanh,
        sqrt,
        cbrt,
        exp,
        ln/log,
        atan2: 2,
        sin_cos/sincos -> 2,
        rem_euclid: 2,
    );
    fn powi(self, i: i32) -> Self;
}

impl F64Math for f64 {
    trait_impl!(
        abs/fabs,
        copysign: 2,
        sin,
        cos,
        tan,
        sinh,
        cosh,
        tanh,
        asin,
        acos,
        atan,
        atanh,
        sqrt,
        cbrt,
        exp,
        ln/log,
        atan2: 2,
        sin_cos/sincos -> 2,
    );

    /// This custom version of powi only supports values of 2 or 3.
    #[inline]
    fn powi(self, i: i32) -> Self {
        let square = self * self;

        match i {
            2 => square,
            3 => square * self,
            _ => unreachable!("F64Math::powi only supports exp values of 2 or 3"),
        }
    }

    /// Copied from source of [`core::f64::math::rem_euclid`]
    fn rem_euclid(self, rhs: f64) -> Self {
        let r = self % rhs;
        if r < 0.0 {
            r + rhs.abs()
        } else {
            r
        }
    }

    fn signum(self) -> Self {
        libm::copysign(1.0, self)
    }
}