celestial_pointing/commands/
show.rs1use 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}