use hifitime::{Duration, TimeScale, Unit};
use tabled::{settings::Style, Table, Tabled};
use crate::naif::daf::NAIFSummaryRecord;
use super::{BPC, SPK};
#[derive(Tabled)]
pub struct BpcRow {
#[tabled(rename = "Name")]
pub name: String,
#[tabled(rename = "Start epoch")]
pub start_epoch: String,
#[tabled(rename = "End epoch")]
pub end_epoch: String,
#[tabled(rename = "Duration")]
pub duration: Duration,
#[tabled(rename = "Interpolation kind")]
pub interpolation_kind: String,
#[tabled(rename = "Frame")]
pub frame: String,
#[tabled(rename = "Inertial frame")]
pub inertial_frame: String,
}
#[derive(Tabled)]
pub struct SpkRow {
#[tabled(rename = "Name")]
pub name: String,
#[tabled(rename = "Target")]
pub target: String,
#[tabled(rename = "Center")]
pub center: String,
#[tabled(rename = "Start epoch")]
pub start_epoch: String,
#[tabled(rename = "End epoch")]
pub end_epoch: String,
#[tabled(rename = "Duration")]
pub duration: Duration,
#[tabled(rename = "Interpolation kind")]
pub interpolation_kind: String,
}
pub trait NAIFPrettyPrint {
fn describe(&self) -> String {
self.describe_in(TimeScale::ET, None)
}
fn describe_in(&self, time_scale: TimeScale, round: Option<bool>) -> String;
}
impl NAIFPrettyPrint for BPC {
fn describe_in(&self, time_scale: TimeScale, round: Option<bool>) -> String {
let mut rows = Vec::new();
let round_value = if round.unwrap_or(true) {
Unit::Second * 1.0_f64
} else {
Unit::Second * 0
};
let mut idx = None;
loop {
for (sno, summary) in self.data_summaries(idx).unwrap().iter().enumerate() {
let name_rcrd = self.name_record(idx).unwrap();
let name = name_rcrd.nth_name(sno, self.file_record().unwrap().summary_size());
if summary.is_empty() {
continue;
}
rows.push(BpcRow {
name: name.to_string(),
start_epoch: summary
.start_epoch()
.to_gregorian_str(time_scale)
.to_string(),
end_epoch: summary.end_epoch().to_gregorian_str(time_scale).to_string(),
duration: (summary.end_epoch() - summary.start_epoch()).round(round_value),
interpolation_kind: summary.data_type().unwrap().to_string(),
frame: format!("{}", summary.frame_id),
inertial_frame: format!("{}", summary.inertial_frame_id),
});
}
if let Ok(summary) = self.daf_summary(idx) {
if summary.is_final_record() {
break;
} else {
idx = Some(summary.next_record());
}
}
}
let mut tbl = Table::new(rows);
tbl.with(Style::modern());
format!("{tbl}")
}
}
impl NAIFPrettyPrint for SPK {
fn describe_in(&self, time_scale: TimeScale, round: Option<bool>) -> String {
let mut rows = Vec::new();
let round_value = if round.unwrap_or(true) {
Unit::Second * 1.0_f64
} else {
Unit::Second * 0
};
let mut idx = None;
loop {
for (sno, summary) in self.data_summaries(idx).unwrap().iter().enumerate() {
let name_rcrd = self.name_record(idx).unwrap();
let name = name_rcrd.nth_name(sno, self.file_record().unwrap().summary_size());
if summary.is_empty() {
continue;
}
rows.push(SpkRow {
name: name.to_string(),
center: summary.center_frame_uid().to_string(),
start_epoch: summary
.start_epoch()
.to_gregorian_str(time_scale)
.to_string(),
end_epoch: summary.end_epoch().to_gregorian_str(time_scale).to_string(),
duration: (summary.end_epoch() - summary.start_epoch()).round(round_value),
interpolation_kind: summary.data_type().unwrap().to_string(),
target: summary.target_frame_uid().to_string(),
});
}
if let Ok(summary) = self.daf_summary(idx) {
if summary.is_final_record() {
break;
} else {
idx = Some(summary.next_record());
}
}
}
let mut tbl = Table::new(rows);
tbl.with(Style::sharp());
format!("{tbl}")
}
}