Skip to main content

celestial_pointing/commands/
show.rs

1use super::{Command, CommandOutput};
2use crate::error::Result;
3use crate::observation::MountType;
4use crate::session::Session;
5
6pub struct Show;
7
8impl Command for Show {
9    fn name(&self) -> &str {
10        "SHOW"
11    }
12    fn description(&self) -> &str {
13        "Display session state"
14    }
15
16    fn execute(&self, session: &mut Session, _args: &[&str]) -> Result<CommandOutput> {
17        let mount = match session.mount_type {
18            MountType::GermanEquatorial => "German Equatorial",
19            MountType::ForkEquatorial => "Fork Equatorial",
20            MountType::Altazimuth => "Altazimuth",
21        };
22
23        let lat_str = session
24            .site
25            .as_ref()
26            .map(|s| format_dms_lat(s.latitude.degrees()))
27            .unwrap_or_else(|| "not set".to_string());
28
29        let masked = session.masked_observation_count();
30        let total = session.observation_count();
31        let obs_str = if masked > 0 {
32            format!("{} ({} masked)", total, masked)
33        } else {
34            format!("{}", total)
35        };
36
37        let rms_str = session
38            .last_fit
39            .as_ref()
40            .map(|f| format!("{:.2}\"", f.sky_rms))
41            .unwrap_or_else(|| "no fit yet".to_string());
42
43        let output = format!(
44            "Mount type: {}\nSite latitude: {}\nObservations: {}\nModel terms: {}\nLast fit RMS: {}",
45            mount, lat_str, obs_str, session.model.term_count(), rms_str,
46        );
47
48        Ok(CommandOutput::Text(output))
49    }
50}
51
52fn format_dms_lat(deg: f64) -> String {
53    let sign = if deg < 0.0 { "-" } else { "+" };
54    let total = deg.abs();
55    let d = total as i32;
56    let rem = (total - d as f64) * 60.0;
57    let m = rem as i32;
58    let s = (rem - m as f64) * 60.0;
59    format!("{}{} {:02} {:02}", sign, d, m, s as i32)
60}