rust-spice 0.7.8

WOW! The complete NASA/NAIF Spice toolkit is actually usable on Rust.
Documentation
#[macro_use]
extern crate approx;
extern crate nalgebra as na;
extern crate spice;
#[macro_use]
extern crate serial_test;

#[cfg(not(feature = "lock"))]
mod core;

use std::ffi::CString;

#[test]
#[serial]
fn test_c() {
    unsafe {
        let kernel = CString::new("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm")
            .unwrap()
            .into_raw();
        spice::c::furnsh_c(kernel);
        spice::c::unload_c(kernel);
    }
}

#[cfg(feature = "lock")]
pub mod lock_tests {
    #[test]
    #[serial]
    fn acquire_fail() {
        let _sl = spice::SpiceLock::try_acquire().unwrap();
        assert!(spice::SpiceLock::try_acquire().is_err());
    }
    #[test]
    #[serial]
    fn reacquire() {
        let sl = spice::SpiceLock::try_acquire().unwrap();
        drop(sl);

        let try_new_sl = spice::SpiceLock::try_acquire();
        assert!(try_new_sl.is_ok());
    }
    #[test]
    #[serial]
    fn str2et() {
        let sl = spice::SpiceLock::try_acquire().unwrap();
        sl.furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");

        let et = sl.str2et("2027-MAR-23 16:00:00");

        assert_relative_eq!(et, 859089669.1856234, epsilon = f64::EPSILON);

        sl.unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
    }
    #[test]
    #[serial]
    fn spkezr() {
        let sl = spice::SpiceLock::try_acquire().unwrap();

        sl.furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");

        // an arbitrary time
        let et = sl.str2et("2021-01-06 09:36:09.1825432 TDB");

        // sun in relation to ssb
        let (sun_ssb_posvec, _sun_ssb_lt) = sl.spkezr("sun", et, "j2000", "none", "ssb");
        // earth in relation to ssb
        let (earth_ssb_posvec, _earth_ssb_lt) = sl.spkezr("earth", et, "j2000", "none", "ssb");
        // earth in relation to sun
        let (earth_sun_posvec, _earth_sun_ly) = sl.spkezr("earth", et, "j2000", "none", "sun");

        // Quick check that the (Sun relative) earth velocity vectors are the same regardless of whether we
        // calculate them indirectly from SB or directly compared to  the Sun
        assert_eq!(earth_ssb_posvec[3] - sun_ssb_posvec[3], earth_sun_posvec[3]);
        assert_eq!(earth_ssb_posvec[4] - sun_ssb_posvec[4], earth_sun_posvec[4]);
        assert_eq!(earth_ssb_posvec[5] - sun_ssb_posvec[5], earth_sun_posvec[5]);

        sl.unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
    }
    #[test]
    #[serial]
    fn cell() {
        let sl = spice::SpiceLock::try_acquire().unwrap();

        sl.furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");

        let (file, _, _, _, found) = sl.kdata(1, "dsk");
        assert!(found);

        let cell = sl.dskobj(&file);

        assert_eq!(cell.card, 1);
        assert_eq!(cell.get_data_int(0), -658031);

        assert_eq!(sl.bodc2n(cell.get_data_int(0)).0, "DIMORPHOS");

        sl.kclear();
    }
    #[test]
    #[serial]
    fn multiple_threads() {
        use std::sync::{Arc, Mutex};
        use std::thread;

        let sl = spice::SpiceLock::try_acquire().unwrap();
        sl.furnsh("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");

        let sl = Arc::new(Mutex::new(sl));

        let n_children = 5;
        let mut children = Vec::with_capacity(n_children);

        for _ in 0..n_children {
            let sl = Arc::clone(&sl);
            children.push(thread::spawn(move || {
                for _ in 0..10 {
                    // If these calls were not guarded by the lock, they could lead to data races and UB
                    sl.lock().unwrap().str2et("2027-MAR-23 16:00:00");
                }
            }));
        }

        for c in children {
            c.join().unwrap();
        }

        sl.lock()
            .unwrap()
            .unload("/Users/gregoireh/data/spice-kernels/hera/kernels/mk/hera_study_PO_EMA_2024.tm");
    }
}