celestial_pointing/commands/
indat.rs1use super::{Command, CommandOutput};
2use crate::error::Result;
3use crate::observation::{MountType, PierSide};
4use crate::parser::parse_indat;
5use crate::session::Session;
6
7pub struct Indat;
8
9impl Command for Indat {
10 fn name(&self) -> &str {
11 "INDAT"
12 }
13 fn description(&self) -> &str {
14 "Load observations from INDAT file"
15 }
16
17 fn execute(&self, session: &mut Session, args: &[&str]) -> Result<CommandOutput> {
18 if args.is_empty() {
19 return Err(crate::error::Error::Parse(
20 "INDAT requires a filename".into(),
21 ));
22 }
23 let content = std::fs::read_to_string(args[0]).map_err(crate::error::Error::Io)?;
24 let indat = parse_indat(&content)?;
25 let summary = format_summary(&indat);
26 session.load_indat(indat);
27 Ok(CommandOutput::Text(summary))
28 }
29}
30
31fn format_summary(indat: &crate::observation::IndatFile) -> String {
32 let mount = match indat.mount_type {
33 MountType::GermanEquatorial => "German Equatorial",
34 MountType::ForkEquatorial => "Fork Equatorial",
35 MountType::Altazimuth => "Altazimuth",
36 };
37 let lat = format_dms(indat.site.latitude.degrees());
38 let n = indat.observations.len();
39 let east = indat
40 .observations
41 .iter()
42 .filter(|o| o.pier_side == PierSide::East)
43 .count();
44 let west = indat
45 .observations
46 .iter()
47 .filter(|o| o.pier_side == PierSide::West)
48 .count();
49 format!(
50 "{} observations loaded\n Mount: {}\n Latitude: {}\n Pier: {} east, {} west",
51 n, mount, lat, east, west,
52 )
53}
54
55fn format_dms(deg: f64) -> String {
56 let sign = if deg < 0.0 { "-" } else { "+" };
57 let total = deg.abs();
58 let d = total as i32;
59 let rem = (total - d as f64) * 60.0;
60 let m = rem as i32;
61 let s = (rem - m as f64) * 60.0;
62 format!("{}{}d {:02}' {:02}\"", sign, d, m, s as i32)
63}