use super::CacheStatusReport;
use crate::{
duration::display_duration_seconds,
human_quantity::byte_count_text,
table::{ColumnAlign, render_table},
text_value::{sanitize_text, yes_no},
};
#[must_use]
pub fn cache_status_report_text(report: &CacheStatusReport) -> String {
let mut lines = vec![
format!("cache_root: {}", sanitize_text(&report.cache_root)),
format!("cache_root_found: {}", yes_no(report.cache_root_found)),
format!("inspected_at: {}", sanitize_text(&report.inspected_at)),
format!(
"family_validation_performed: {}",
yes_no(report.family_validation_performed)
),
format!("cache_count: {}", report.cache_count),
format!("readable_headers: {}", report.readable_header_count),
format!("invalid_headers: {}", report.invalid_header_count),
format!("fresh: {}", report.fresh_count),
format!("stale: {}", report.stale_count),
format!("unmanaged_age: {}", report.unmanaged_age_count),
format!("unknown_age: {}", report.unknown_age_count),
format!(
"total_size_bytes: {}",
byte_count_text(u128::from(report.total_size_bytes))
),
format!("refresh_locks: {}", report.refresh_lock_count),
format!("active_refresh_locks: {}", report.active_refresh_lock_count),
format!("stale_refresh_locks: {}", report.stale_refresh_lock_count),
format!(
"invalid_refresh_locks: {}",
report.invalid_refresh_lock_count
),
format!(
"refresh_lock_size_bytes: {}",
byte_count_text(u128::from(report.refresh_lock_size_bytes))
),
format!("truncated: {}", yes_no(report.truncated)),
];
append_cache_rows(&mut lines, report);
append_refresh_lock_rows(&mut lines, report);
lines.join("\n")
}
fn append_cache_rows(lines: &mut Vec<String>, report: &CacheStatusReport) {
if !report.caches.is_empty() {
lines.push(String::new());
lines.push(render_table(
&[
"HEADER",
"AGE STATE",
"INVALID RECOVERY",
"COMPONENT",
"AGE",
"STALE AFTER",
"BYTES",
"PATH",
],
&report
.caches
.iter()
.map(|row| {
[
row.header_status.as_str().to_string(),
row.age_status.as_str().to_string(),
row.recovery_policy.as_str().to_string(),
row.component.clone(),
row.age_seconds
.map_or_else(|| "-".to_string(), display_duration_seconds),
row.stale_after_seconds
.map_or_else(|| "-".to_string(), display_duration_seconds),
byte_count_text(u128::from(row.size_bytes)),
row.relative_path.clone(),
]
})
.collect::<Vec<_>>(),
&[
ColumnAlign::Left,
ColumnAlign::Left,
ColumnAlign::Left,
ColumnAlign::Left,
ColumnAlign::Right,
ColumnAlign::Right,
ColumnAlign::Right,
ColumnAlign::Left,
],
));
for row in report
.caches
.iter()
.filter(|row| row.inspection_error.is_some())
{
lines.push(format!(
"cache_inspection_error[{}]: {}",
sanitize_text(&row.relative_path),
sanitize_text(row.inspection_error.as_deref().unwrap_or_default())
));
}
}
}
fn append_refresh_lock_rows(lines: &mut Vec<String>, report: &CacheStatusReport) {
if !report.refresh_locks.is_empty() {
lines.push(String::new());
lines.push("REFRESH LOCKS".to_string());
lines.push(render_table(
&["STATUS", "COMPONENT", "AGE", "STALE AFTER", "PID", "PATH"],
&report
.refresh_locks
.iter()
.map(|row| {
[
row.status.as_str().to_string(),
row.component.clone(),
row.age_seconds
.map_or_else(|| "-".to_string(), display_duration_seconds),
row.stale_after_seconds
.map_or_else(|| "-".to_string(), display_duration_seconds),
row.pid
.map_or_else(|| "-".to_string(), |pid| pid.to_string()),
row.relative_path.clone(),
]
})
.collect::<Vec<_>>(),
&[
ColumnAlign::Left,
ColumnAlign::Left,
ColumnAlign::Right,
ColumnAlign::Right,
ColumnAlign::Right,
ColumnAlign::Left,
],
));
for row in report
.refresh_locks
.iter()
.filter(|row| row.error.is_some())
{
lines.push(format!(
"refresh_lock_error[{}]: {}",
sanitize_text(&row.relative_path),
sanitize_text(row.error.as_deref().unwrap_or_default())
));
}
}
}