1use std::os::raw::{c_char, c_double, c_int};
15
16pub const SE_SUN: c_int = 0;
20pub const SE_MOON: c_int = 1;
21pub const SE_MERCURY: c_int = 2;
22pub const SE_VENUS: c_int = 3;
23pub const SE_MARS: c_int = 4;
24pub const SE_JUPITER: c_int = 5;
25pub const SE_SATURN: c_int = 6;
26pub const SE_URANUS: c_int = 7;
27pub const SE_NEPTUNE: c_int = 8;
28pub const SE_PLUTO: c_int = 9;
29pub const SE_MEAN_NODE: c_int = 10;
30pub const SE_TRUE_NODE: c_int = 11;
31pub const SE_MEAN_APOG: c_int = 12;
32pub const SE_OSCU_APOG: c_int = 13;
33pub const SE_EARTH: c_int = 14;
34pub const SE_CHIRON: c_int = 15;
35pub const SE_PHOLUS: c_int = 16;
36pub const SE_CERES: c_int = 17;
37pub const SE_PALLAS: c_int = 18;
38pub const SE_JUNO: c_int = 19;
39pub const SE_VESTA: c_int = 20;
40pub const SE_AST_OFFSET: c_int = 10000;
43
44pub const SE_JUL_CAL: c_int = 0;
48pub const SE_GREG_CAL: c_int = 1;
49
50pub const SEFLG_JPLEPH: c_int = 1;
54pub const SEFLG_SWIEPH: c_int = 2;
55pub const SEFLG_MOSEPH: c_int = 4;
56pub const SEFLG_HELCTR: c_int = 8;
57pub const SEFLG_TRUEPOS: c_int = 16;
58pub const SEFLG_J2000: c_int = 32;
59pub const SEFLG_NONUT: c_int = 64;
60pub const SEFLG_SPEED3: c_int = 128;
61pub const SEFLG_SPEED: c_int = 256;
62pub const SEFLG_NOGDEFL: c_int = 512;
63pub const SEFLG_NOABERR: c_int = 1024;
64pub const SEFLG_ASTROMETRIC: c_int = SEFLG_NOABERR | SEFLG_NOGDEFL;
65pub const SEFLG_EQUATORIAL: c_int = 2048;
66pub const SEFLG_XYZ: c_int = 4096;
67pub const SEFLG_RADIANS: c_int = 8192;
68pub const SEFLG_BARYCTR: c_int = 16384;
69pub const SEFLG_TOPOCTR: c_int = 32768;
70pub const SEFLG_SIDEREAL: c_int = 65536;
71
72pub const SE_SIDM_FAGAN_BRADLEY: c_int = 0;
76pub const SE_SIDM_LAHIRI: c_int = 1;
77pub const SE_SIDM_DELUCE: c_int = 2;
78pub const SE_SIDM_RAMAN: c_int = 3;
79pub const SE_SIDM_KRISHNAMURTI: c_int = 5;
80
81pub const SE_ECL_CENTRAL: c_int = 1;
85pub const SE_ECL_NONCENTRAL: c_int = 2;
86pub const SE_ECL_TOTAL: c_int = 4;
87pub const SE_ECL_ANNULAR: c_int = 8;
88pub const SE_ECL_PARTIAL: c_int = 16;
89pub const SE_ECL_ANNULAR_TOTAL: c_int = 32;
90pub const SE_ECL_PENUMBRAL: c_int = 64;
91
92pub const SE_MAX_STNAME: usize = 256;
94
95extern "C" {
96 pub fn swe_set_ephe_path(path: *const c_char);
97 pub fn swe_close();
98 pub fn swe_version(svers: *mut c_char) -> *mut c_char;
99
100 pub fn swe_calc_ut(
101 tjd_ut: c_double,
102 ipl: c_int,
103 iflag: c_int,
104 xx: *mut c_double,
105 serr: *mut c_char,
106 ) -> c_int;
107
108 pub fn swe_calc(
109 tjd_et: c_double,
110 ipl: c_int,
111 iflag: c_int,
112 xx: *mut c_double,
113 serr: *mut c_char,
114 ) -> c_int;
115
116 pub fn swe_get_planet_name(ipl: c_int, name: *mut c_char) -> *mut c_char;
117
118 pub fn swe_julday(
119 year: c_int,
120 month: c_int,
121 day: c_int,
122 hour: c_double,
123 gregflag: c_int,
124 ) -> c_double;
125
126 pub fn swe_revjul(
127 jd: c_double,
128 gregflag: c_int,
129 jyear: *mut c_int,
130 jmon: *mut c_int,
131 jday: *mut c_int,
132 jut: *mut c_double,
133 );
134
135 pub fn swe_utc_to_jd(
136 iyear: c_int,
137 imonth: c_int,
138 iday: c_int,
139 ihour: c_int,
140 imin: c_int,
141 dsec: c_double,
142 gregflag: c_int,
143 dret: *mut c_double,
144 serr: *mut c_char,
145 ) -> c_int;
146
147 pub fn swe_deltat(tjd: c_double) -> c_double;
148
149 pub fn swe_houses(
150 tjd_ut: c_double,
151 geolat: c_double,
152 geolon: c_double,
153 hsys: c_int,
154 cusps: *mut c_double,
155 ascmc: *mut c_double,
156 ) -> c_int;
157
158 pub fn swe_houses_ex(
159 tjd_ut: c_double,
160 iflag: c_int,
161 geolat: c_double,
162 geolon: c_double,
163 hsys: c_int,
164 cusps: *mut c_double,
165 ascmc: *mut c_double,
166 ) -> c_int;
167
168 pub fn swe_house_name(hsys: c_int) -> *const c_char;
169
170 pub fn swe_set_topo(geolon: c_double, geolat: c_double, geoalt: c_double);
171
172 pub fn swe_set_sid_mode(sid_mode: c_int, t0: c_double, ayan_t0: c_double);
173
174 pub fn swe_get_ayanamsa_ex_ut(
175 tjd_ut: c_double,
176 iflag: c_int,
177 daya: *mut c_double,
178 serr: *mut c_char,
179 ) -> c_int;
180
181 pub fn swe_sol_eclipse_when_glob(
182 tjd_start: c_double,
183 ifl: c_int,
184 ifltype: c_int,
185 tret: *mut c_double,
186 backward: c_int,
187 serr: *mut c_char,
188 ) -> c_int;
189
190 pub fn swe_lun_eclipse_when(
191 tjd_start: c_double,
192 ifl: c_int,
193 ifltype: c_int,
194 tret: *mut c_double,
195 backward: c_int,
196 serr: *mut c_char,
197 ) -> c_int;
198}
199
200#[cfg(test)]
201mod tests {
202 use super::*;
203
204 static TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
208
209 #[test]
210 fn julday_j2000() {
211 let _guard = TEST_LOCK.lock().unwrap();
212 let jd = unsafe { swe_julday(2000, 1, 1, 12.0, SE_GREG_CAL) };
213 assert!((jd - 2451545.0).abs() < 0.0001, "JD was {jd}");
214 }
215
216 #[test]
217 fn calc_sun_position() {
218 let _guard = TEST_LOCK.lock().unwrap();
219 unsafe {
220 let jd = swe_julday(2000, 1, 1, 12.0, SE_GREG_CAL);
221 let mut xx = [0.0_f64; 6];
222 let mut serr = [0i8; SE_MAX_STNAME];
223 let ret = swe_calc_ut(
224 jd,
225 SE_SUN,
226 SEFLG_SPEED | SEFLG_SWIEPH,
227 xx.as_mut_ptr(),
228 serr.as_mut_ptr().cast(),
229 );
230 assert!(ret >= 0, "swe_calc_ut failed: {ret}");
231 let sun_lon = xx[0];
232 assert!(
233 sun_lon > 270.0 && sun_lon < 290.0,
234 "Sun longitude was {sun_lon}"
235 );
236 }
237 }
238
239 #[test]
240 fn version_string() {
241 let _guard = TEST_LOCK.lock().unwrap();
242 let mut buf = [0i8; SE_MAX_STNAME];
243 let s = unsafe {
244 swe_version(buf.as_mut_ptr().cast());
245 std::ffi::CStr::from_ptr(buf.as_ptr().cast())
246 .to_string_lossy()
247 .into_owned()
248 };
249 assert!(s.starts_with("2.10"), "unexpected version: {s}");
250 }
251}