pub mod analyze;
mod format;
pub mod json;
pub mod tree;
use std::io::Write;
use crate::cli::OutputFormat;
use crate::entry::Entry;
pub struct OutputConfig {
pub depth: Option<usize>,
pub top: Option<usize>,
}
pub(crate) fn select_top(children: &[Entry], top: Option<usize>) -> (Vec<&Entry>, usize, u64) {
match top {
None => (children.iter().collect(), 0, 0),
Some(n) if n >= children.len() => (children.iter().collect(), 0, 0),
Some(n) => {
let mut by_size: Vec<(usize, u64)> = children
.iter()
.enumerate()
.map(|(i, e)| (i, e.size))
.collect();
by_size.sort_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
by_size.truncate(n);
let keep: std::collections::BTreeSet<usize> = by_size.iter().map(|&(i, _)| i).collect();
let kept: Vec<&Entry> = children
.iter()
.enumerate()
.filter(|(i, _)| keep.contains(i))
.map(|(_, e)| e)
.collect();
let dropped_size: u64 = children
.iter()
.enumerate()
.filter(|(i, _)| !keep.contains(i))
.map(|(_, e)| e.size)
.sum();
let dropped_count = children.len() - kept.len();
(kept, dropped_count, dropped_size)
}
}
}
pub fn render(
entry: &Entry,
config: &OutputConfig,
format: OutputFormat,
out: &mut impl Write,
) -> anyhow::Result<()> {
match format {
OutputFormat::Tree => tree::write(entry, config, out)?,
OutputFormat::Json => json::write(entry, config, out)?,
OutputFormat::Analyze => analyze::write(entry, out)?,
OutputFormat::Ui => unreachable!("UI format must be handled by main.rs"),
}
Ok(())
}