use std::{
fs::File,
io::{BufReader, Read, Seek},
};
use hifitime::{Duration, Epoch};
use nom::number::complete::le_f64;
#[derive(Debug, PartialEq, Clone)]
pub struct DirectoryData {
pub init: f64,
pub intlen: usize,
pub rsize: usize,
pub n_records: usize,
}
impl DirectoryData {
pub fn parse(file: &mut BufReader<File>, end_addr: usize) -> Self {
let directory_offset_bytes = (end_addr - 4) * 8;
let mut dir_buf = [0u8; 32]; file.seek(std::io::SeekFrom::Start(directory_offset_bytes as u64))
.unwrap();
file.read_exact(&mut dir_buf).unwrap();
let (input, init) = le_f64::<_, nom::error::Error<_>>(dir_buf.as_slice()).unwrap();
let (input, intlen) = le_f64::<_, nom::error::Error<_>>(input).unwrap();
let (input, rsize) = le_f64::<_, nom::error::Error<_>>(input).unwrap();
let (_, n_records) = le_f64::<_, nom::error::Error<_>>(input).unwrap();
DirectoryData {
init,
intlen: intlen as usize,
rsize: rsize as usize,
n_records: n_records as usize,
}
}
}
impl std::fmt::Display for DirectoryData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let epoch = Epoch::from_et_seconds(self.init);
let record_length = Duration::from_seconds(self.intlen as f64);
writeln!(f, "+----------------+----------------------------+")?;
writeln!(f, "| {:<14} | {:<26} |", "Field", "Value")?;
writeln!(f, "+----------------+----------------------------+")?;
writeln!(
f,
"| {:<14} | {:<26} |",
"init (epoch)",
format!("{}", epoch)
)?;
writeln!(
f,
"| {:<14} | {:<26} |",
"intlen",
format!("{}", record_length)
)?;
writeln!(f, "| {:<14} | {:<26} |", "rsize", format!("{}", self.rsize))?;
writeln!(
f,
"| {:<14} | {:<26} |",
"n_records",
format!("{}", self.n_records)
)?;
writeln!(f, "+----------------+----------------------------+")?;
Ok(())
}
}
#[cfg(test)]
mod test_directory {
use super::*;
#[test]
fn test_directory_display() {
let dir_data = DirectoryData {
init: -14200747200.0,
intlen: 1382400,
rsize: 41,
n_records: 25112,
};
let output = format!("{dir_data}");
let expected_output = r#"+----------------+----------------------------+
| Field | Value |
+----------------+----------------------------+
| init (epoch) | 1549-12-31T00:00:00 ET |
| intlen | 16 days |
| rsize | 41 |
| n_records | 25112 |
+----------------+----------------------------+
"#;
assert_eq!(output, expected_output);
}
}