lox-space 0.1.0-alpha.48

The Lox toolbox for space mission analysis and design
Documentation
// SPDX-FileCopyrightText: 2024 Helge Eichhorn <git@helgeeichhorn.de>
//
// SPDX-License-Identifier: MPL-2.0

use std::path::PathBuf;

use pyo3::{
    Bound, PyAny, PyErr, PyResult, exceptions::PyValueError, pyclass, pymethods,
    types::PyAnyMethods,
};

use crate::ephem::spk::parser::{DafSpkError, Spk};

/// PyO3 error wrapper for [`lox_ephem::spk::parser::DafSpkError`].
pub struct PyDafSpkError(pub DafSpkError);

impl From<PyDafSpkError> for PyErr {
    fn from(err: PyDafSpkError) -> Self {
        PyValueError::new_err(err.0.to_string())
    }
}

/// SPICE SPK (Spacecraft and Planet Kernel) ephemeris data.
///
/// SPK files contain position and velocity data for celestial bodies and
/// spacecraft. They are used to compute accurate positions for orbit
/// propagation, frame transformations, and visibility analysis.
///
/// SPK files can be obtained from:
///
/// - NASA NAIF: <https://naif.jpl.nasa.gov/naif/data.html>
/// - ESA SPICE Service: <https://spice.esac.esa.int/>
///
/// Args:
///     path: Path to the SPK file (.bsp).
///
/// Raises:
///     ValueError: If the file cannot be parsed or is invalid.
///     OSError: If the file cannot be read.
#[pyclass(name = "SPK", module = "lox_space", frozen)]
pub struct PySpk(pub Spk);

#[pymethods]
impl PySpk {
    #[new]
    fn new(path: &Bound<'_, PyAny>) -> PyResult<Self> {
        let path = path.extract::<PathBuf>()?;
        let spk = Spk::from_file(path).map_err(PyDafSpkError)?;
        Ok(PySpk(spk))
    }

    fn __repr__(&self) -> String {
        let n: usize = self
            .0
            .segments
            .values()
            .map(|m| m.values().map(|v| v.len()).sum::<usize>())
            .sum();
        format!("SPK({n} segments)")
    }
}