#[derive(Debug, Clone)]
pub struct EmbedStats {
pub templates: CategoryStats,
pub packages: PackageStats,
pub fonts: CategoryStats,
pub dedup: DedupStats,
pub compression_level: i32,
}
#[derive(Debug, Clone, Copy)]
pub struct DedupStats {
pub total_files: usize,
pub unique_blobs: usize,
pub duplicate_count: usize,
pub saved_bytes: usize,
}
#[derive(Debug, Clone, Copy)]
pub struct CategoryStats {
pub original_size: usize,
pub compressed_size: usize,
pub file_count: usize,
}
#[derive(Debug, Clone)]
pub struct PackageStats {
pub packages: Vec<PackageInfo>,
pub original_size: usize,
pub compressed_size: usize,
}
#[derive(Debug, Clone)]
pub struct PackageInfo {
pub name: String,
pub original_size: usize,
pub compressed_size: usize,
pub file_count: usize,
}
impl EmbedStats {
pub fn total_original(&self) -> usize {
self.templates.original_size + self.packages.original_size + self.fonts.original_size
}
pub fn total_compressed(&self) -> usize {
self.templates.compressed_size + self.packages.compressed_size + self.fonts.compressed_size
}
pub fn compression_ratio(&self) -> f64 {
compression_ratio(self.total_original(), self.total_compressed())
}
pub fn total_deduplicated(&self) -> usize {
self.total_compressed() - self.dedup.saved_bytes
}
pub fn overall_ratio(&self) -> f64 {
compression_ratio(self.total_original(), self.total_deduplicated())
}
fn total_file_count(&self) -> usize {
self.templates.file_count
+ self.fonts.file_count
+ self
.packages
.packages
.iter()
.map(|p| p.file_count)
.sum::<usize>()
}
pub fn display(&self) {
print!("{self}");
}
}
impl std::fmt::Display for EmbedStats {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Embed Summary")?;
writeln!(f, "========================")?;
if self.templates.file_count > 0 {
writeln!(
f,
"Templates: {:>9} -> {:>9} ({:>5.1}% reduced, {} files)",
format_size(self.templates.original_size),
format_size(self.templates.compressed_size),
self.templates.compression_ratio() * 100.0,
self.templates.file_count
)?;
}
if self.fonts.file_count > 0 {
writeln!(
f,
"Fonts: {:>9} -> {:>9} ({:>5.1}% reduced, {} files)",
format_size(self.fonts.original_size),
format_size(self.fonts.compressed_size),
self.fonts.compression_ratio() * 100.0,
self.fonts.file_count
)?;
}
if !self.packages.packages.is_empty() {
writeln!(f, "Packages:")?;
let (name_width, orig_width, comp_width) =
self.packages
.packages
.iter()
.fold((0, 0, 0), |(nw, ow, cw), p| {
(
nw.max(p.name.len()),
ow.max(format_size(p.original_size).len()),
cw.max(format_size(p.compressed_size).len()),
)
});
for pkg in &self.packages.packages {
writeln!(
f,
" {:<name_w$} {:>orig_w$} -> {:>comp_w$} ({:>5.1}%)",
pkg.name,
format_size(pkg.original_size),
format_size(pkg.compressed_size),
pkg.compression_ratio() * 100.0,
name_w = name_width,
orig_w = orig_width,
comp_w = comp_width,
)?;
}
}
writeln!(f, "------------------------")?;
writeln!(
f,
"Compressed: {} -> {} (level {}, {:.1}% reduced, {} files)",
format_size(self.total_original()),
format_size(self.total_compressed()),
self.compression_level,
self.compression_ratio() * 100.0,
self.total_file_count()
)?;
if self.dedup.duplicate_count > 0 {
writeln!(
f,
"Deduplicated: {} unique blobs, {} duplicates removed (-{})",
self.dedup.unique_blobs,
self.dedup.duplicate_count,
format_size(self.dedup.saved_bytes)
)?;
}
writeln!(
f,
"Total: {} -> {} ({:.1}% reduced)",
format_size(self.total_original()),
format_size(self.total_deduplicated()),
self.overall_ratio() * 100.0
)
}
}
pub trait HasCompressionRatio {
fn original_size(&self) -> usize;
fn compressed_size(&self) -> usize;
fn compression_ratio(&self) -> f64 {
compression_ratio(self.original_size(), self.compressed_size())
}
}
macro_rules! impl_has_compression_ratio {
($($ty:ty),*) => {
$(impl HasCompressionRatio for $ty {
fn original_size(&self) -> usize { self.original_size }
fn compressed_size(&self) -> usize { self.compressed_size }
})*
};
}
impl_has_compression_ratio!(CategoryStats, PackageInfo, PackageStats);
fn compression_ratio(original: usize, compressed: usize) -> f64 {
if original == 0 {
return 0.0;
}
1.0 - (compressed as f64 / original as f64)
}
fn format_size(bytes: usize) -> String {
const KB: usize = 1024;
const MB: usize = KB * 1024;
if bytes >= MB {
format!("{:.2} MB", bytes as f64 / MB as f64)
} else if bytes >= KB {
format!("{:.1} KB", bytes as f64 / KB as f64)
} else {
format!("{bytes} B")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_size_bytes() {
assert_eq!(format_size(0), "0 B");
assert_eq!(format_size(512), "512 B");
assert_eq!(format_size(1023), "1023 B");
}
#[test]
fn test_format_size_kilobytes() {
assert_eq!(format_size(1024), "1.0 KB");
assert_eq!(format_size(1536), "1.5 KB");
assert_eq!(format_size(10240), "10.0 KB");
}
#[test]
fn test_format_size_megabytes() {
assert_eq!(format_size(1048576), "1.00 MB");
assert_eq!(format_size(1572864), "1.50 MB");
}
#[test]
fn test_compression_ratio_zero_original() {
let stats = CategoryStats {
original_size: 0,
compressed_size: 0,
file_count: 0,
};
assert_eq!(stats.compression_ratio(), 0.0);
}
#[test]
fn test_compression_ratio_75_percent() {
let stats = CategoryStats {
original_size: 1000,
compressed_size: 250,
file_count: 1,
};
assert!((stats.compression_ratio() - 0.75).abs() < 0.001);
}
#[test]
fn test_embed_stats_totals() {
let stats = EmbedStats {
templates: CategoryStats {
original_size: 1000,
compressed_size: 200, file_count: 1,
},
fonts: CategoryStats {
original_size: 2000,
compressed_size: 600, file_count: 2,
},
packages: PackageStats {
packages: vec![],
original_size: 1000,
compressed_size: 200, },
dedup: DedupStats {
total_files: 4,
unique_blobs: 3,
duplicate_count: 1,
saved_bytes: 100,
},
compression_level: 19,
};
assert_eq!(stats.total_original(), 4000);
assert_eq!(stats.total_compressed(), 1000);
assert!((stats.compression_ratio() - 0.75).abs() < 0.001);
assert_eq!(stats.total_deduplicated(), 900);
}
}