Skip to main content

siderust_py/
lib.rs

1//! Python bindings for siderust astrometry and astrodynamics.
2//!
3//! This crate provides Python bindings for the siderust Rust library, enabling
4//! observation planning, coordinate transforms, altitude/azimuth queries, and
5//! ephemeris access from Python — all backed by Rust for performance.
6
7use pyo3::prelude::*;
8
9mod bodies;
10mod coordinates;
11mod ephemeris;
12mod errors;
13mod events;
14pub mod interop;
15mod observer;
16mod orbit;
17mod phase;
18mod position;
19mod queries;
20mod star;
21mod target;
22
23use bodies::PyBody;
24use coordinates::PyDirection;
25use ephemeris::PyRuntimeEphemeris;
26use events::{PyCrossingDirection, PyCrossingEvent, PyCulminationEvent, PyCulminationKind};
27use observer::PyObserver;
28use orbit::{PyComet, PyOrbit};
29use phase::{PyMoonPhaseGeometry, PyMoonPhaseLabel, PyPhaseEvent, PyPhaseKind};
30use position::{PyPosition, PySphericalPosition};
31use star::PyStar;
32use target::{PyProperMotion, PyTarget};
33
34/// siderust: Astrometry & Astrodynamics for Python
35///
36/// This module provides observation planning, coordinate transforms,
37/// altitude/azimuth queries, and ephemeris access, powered by Rust.
38///
39/// Example:
40/// >>> from siderust import Observer, Body
41/// >>> obs = Observer.roque_de_los_muchachos()
42/// >>> from tempoch import ModifiedJulianDate
43/// >>> mjd = ModifiedJulianDate(60000.0)
44/// >>> alt = Body.Sun.altitude_at(obs, mjd.value)
45/// >>> print(f"Sun altitude: {alt:.4f} deg")
46#[pymodule]
47fn _siderust(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
48    // Core types
49    m.add_class::<PyObserver>()?;
50    m.add_class::<PyBody>()?;
51    m.add_class::<PyStar>()?;
52    m.add_class::<PyDirection>()?;
53    m.add_class::<PyPosition>()?;
54    m.add_class::<PySphericalPosition>()?;
55
56    // Event types
57    m.add_class::<PyCrossingEvent>()?;
58    m.add_class::<PyCulminationEvent>()?;
59    m.add_class::<PyCrossingDirection>()?;
60    m.add_class::<PyCulminationKind>()?;
61
62    // Moon phase types
63    m.add_class::<PyMoonPhaseGeometry>()?;
64    m.add_class::<PyMoonPhaseLabel>()?;
65    m.add_class::<PyPhaseEvent>()?;
66    m.add_class::<PyPhaseKind>()?;
67
68    // Orbit / target / ephemeris types
69    m.add_class::<PyOrbit>()?;
70    m.add_class::<PyComet>()?;
71    m.add_class::<PyProperMotion>()?;
72    m.add_class::<PyTarget>()?;
73    m.add_class::<PyRuntimeEphemeris>()?;
74
75    // Free functions
76    m.add_function(wrap_pyfunction!(queries::altitude_at, m)?)?;
77    m.add_function(wrap_pyfunction!(queries::above_threshold, m)?)?;
78    m.add_function(wrap_pyfunction!(queries::below_threshold, m)?)?;
79    m.add_function(wrap_pyfunction!(queries::crossings, m)?)?;
80    m.add_function(wrap_pyfunction!(queries::culminations, m)?)?;
81    m.add_function(wrap_pyfunction!(queries::azimuth_at, m)?)?;
82    m.add_function(wrap_pyfunction!(queries::intersect_periods, m)?)?;
83    m.add_function(wrap_pyfunction!(phase::moon_phase, m)?)?;
84    m.add_function(wrap_pyfunction!(phase::find_moon_phases, m)?)?;
85    m.add_function(wrap_pyfunction!(target::apply_proper_motion, m)?)?;
86
87    // Private canonical-extension hooks used by the public Rust interop API.
88    m.add_function(wrap_pyfunction!(observer::_bridge_observer_to_parts, m)?)?;
89    m.add_function(wrap_pyfunction!(observer::_bridge_observer_from_parts, m)?)?;
90    m.add_function(wrap_pyfunction!(
91        coordinates::_bridge_direction_to_parts,
92        m
93    )?)?;
94    m.add_function(wrap_pyfunction!(
95        coordinates::_bridge_direction_from_parts,
96        m
97    )?)?;
98    m.add("_bridge_protocol_version", interop::BRIDGE_PROTOCOL_VERSION)?;
99
100    // Twilight constants
101    m.add("TWILIGHT_HORIZON", queries::TWILIGHT_HORIZON)?;
102    m.add("TWILIGHT_CIVIL", queries::TWILIGHT_CIVIL)?;
103    m.add("TWILIGHT_NAUTICAL", queries::TWILIGHT_NAUTICAL)?;
104    m.add("TWILIGHT_ASTRONOMICAL", queries::TWILIGHT_ASTRONOMICAL)?;
105
106    // Version
107    m.add("__version__", env!("CARGO_PKG_VERSION"))?;
108
109    Ok(())
110}