celestial_pointing/terms/
mod.rs1pub mod altaz;
2pub mod equatorial;
3pub mod harmonic;
4
5use crate::error::{Error, Result};
6use bitflags::bitflags;
7
8bitflags! {
9 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
10 pub struct MountTypeFlags: u8 {
11 const EQUATORIAL = 0b001;
12 const ALTAZ = 0b010;
13 const ALL = 0b111;
14 }
15}
16
17pub trait Term: Send + Sync {
18 fn name(&self) -> &str;
19 fn description(&self) -> &str;
20
21 fn jacobian_equatorial(&self, h: f64, dec: f64, lat: f64, pier: f64) -> (f64, f64);
22 fn jacobian_altaz(&self, az: f64, el: f64, lat: f64) -> (f64, f64);
23
24 fn pier_sensitive(&self) -> bool {
25 false
26 }
27 fn applicable_mounts(&self) -> MountTypeFlags;
28}
29
30pub fn create_term(name: &str) -> Result<Box<dyn Term>> {
31 match name.to_uppercase().as_str() {
32 "IH" => Ok(Box::new(equatorial::IH)),
33 "ID" => Ok(Box::new(equatorial::ID)),
34 "CH" => Ok(Box::new(equatorial::CH)),
35 "NP" => Ok(Box::new(equatorial::NP)),
36 "MA" => Ok(Box::new(equatorial::MA)),
37 "ME" => Ok(Box::new(equatorial::ME)),
38 "TF" => Ok(Box::new(equatorial::TF)),
39 "TX" => Ok(Box::new(equatorial::TX)),
40 "DAF" => Ok(Box::new(equatorial::DAF)),
41 "FO" => Ok(Box::new(equatorial::FO)),
42 "HCES" => Ok(Box::new(equatorial::HCES)),
43 "HCEC" => Ok(Box::new(equatorial::HCEC)),
44 "DCES" => Ok(Box::new(equatorial::DCES)),
45 "DCEC" => Ok(Box::new(equatorial::DCEC)),
46 "IA" => Ok(Box::new(altaz::IA)),
47 "IE" => Ok(Box::new(altaz::IE)),
48 "CA" => Ok(Box::new(altaz::CA)),
49 "NPAE" => Ok(Box::new(altaz::NPAE)),
50 "AN" => Ok(Box::new(altaz::AN)),
51 "AW" => Ok(Box::new(altaz::AW)),
52 name if name.starts_with('H') => {
53 let spec = harmonic::parse_harmonic(name)?;
54 Ok(Box::new(spec))
55 }
56 _ => Err(Error::UnknownTerm(name.to_string())),
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn create_known_equatorial_terms() {
66 let names = [
67 "IH", "ID", "CH", "NP", "MA", "ME", "TF", "TX", "DAF", "FO", "HCES", "HCEC", "DCES",
68 "DCEC",
69 ];
70 for name in &names {
71 let term = create_term(name).unwrap();
72 assert_eq!(term.name(), *name);
73 assert_eq!(term.applicable_mounts(), MountTypeFlags::EQUATORIAL);
74 }
75 }
76
77 #[test]
78 fn create_known_altaz_terms() {
79 let names = ["IA", "IE", "CA", "NPAE", "AN", "AW"];
80 for name in &names {
81 let term = create_term(name).unwrap();
82 assert_eq!(term.name(), *name);
83 assert_eq!(term.applicable_mounts(), MountTypeFlags::ALTAZ);
84 }
85 }
86
87 #[test]
88 fn create_harmonic_term() {
89 let term = create_term("HDSH").unwrap();
90 assert_eq!(term.name(), "HDSH");
91 assert_eq!(term.applicable_mounts(), MountTypeFlags::EQUATORIAL);
92 }
93
94 #[test]
95 fn unknown_term_returns_error() {
96 let result = create_term("ZZZZ");
97 assert!(result.is_err());
98 }
99
100 #[test]
101 fn case_insensitive_lookup() {
102 let term = create_term("ih").unwrap();
103 assert_eq!(term.name(), "IH");
104 }
105}