use core::fmt::Write as _;
use crate::findings::MbrAnalysis;
#[must_use]
pub fn text_report(a: &MbrAnalysis) -> String {
let mut s = String::new();
let _ = writeln!(s, "MBR Forensic Analysis");
let _ = writeln!(s, " disk signature : {:#010x}", a.disk_serial);
let _ = writeln!(s, " boot code : {:?}", a.boot_code_id);
let _ = writeln!(s, " partitioning : {:?}", a.era);
let _ = writeln!(s, "\nPartition table ({} entries):", a.partitions.len());
if a.partitions.is_empty() {
let _ = writeln!(s, " (no primary partitions)");
}
for p in &a.partitions {
let fs = match p.detected_fs {
Some(fs) => format!("{fs:?}"),
None => "-".to_string(),
};
let _ = writeln!(
s,
" [{}] {:<24} LBA {:>12}..={:<12} fs={}",
p.index,
p.declared_type.name(),
p.lba_start,
p.lba_end,
fs,
);
}
if a.anomalies.is_empty() {
let _ = writeln!(s, "\nAnomalies: none");
} else {
let _ = writeln!(s, "\nAnomalies ({}):", a.anomalies.len());
for an in &a.anomalies {
let _ = writeln!(s, " {an}");
}
}
#[cfg(feature = "gpt")]
if let Some(gpt) = &a.gpt {
let _ = writeln!(
s,
"\nGPT cross-check: {} partition entries, {} GPT anomalies",
gpt.partitions.len(),
gpt.anomalies.len(),
);
}
match a.max_severity() {
Some(sev) => {
let _ = writeln!(s, "\nHighest severity: {sev}");
}
None => {
let _ = writeln!(s, "\nHighest severity: none (clean)");
}
}
s
}