use core::{mem, ptr::NonNull};
use std::{ffi::CString, path::Path};
use supernovas_ffi::{calceph_close, calceph_open, novas_use_calceph, t_calcephbin};
use super::EphemerisProvider;
use crate::error::{Error, Result};
pub struct CalcephEphemeris {
handle: NonNull<t_calcephbin>,
}
impl CalcephEphemeris {
pub fn open(path: impl AsRef<Path>) -> Result<Self> {
let path = path.as_ref();
let path_str = path.to_str().ok_or(Error::Ephemeris)?;
let cstr = CString::new(path_str).map_err(|_| Error::Ephemeris)?;
let raw = unsafe { calceph_open(cstr.as_ptr()) };
let handle = NonNull::new(raw).ok_or(Error::Ephemeris)?;
Ok(CalcephEphemeris { handle })
}
}
impl EphemerisProvider for CalcephEphemeris {
fn install(self) -> Result<()> {
let rc = unsafe { novas_use_calceph(self.handle.as_ptr()) };
if rc != 0 {
return Err(Error::Ephemeris);
}
mem::forget(self);
Ok(())
}
}
impl Drop for CalcephEphemeris {
fn drop(&mut self) {
unsafe { calceph_close(self.handle.as_ptr()) }
}
}
unsafe impl Send for CalcephEphemeris {}