1pub mod comment_storage;
14pub mod error;
16pub mod html;
18#[cfg(target_arch = "wasm32")]
20pub mod js;
21#[cfg(feature = "server")]
23pub mod server;
24#[cfg(feature = "server")]
26pub mod text;
27pub mod time;
29#[cfg(any(feature = "server", test))]
31pub mod toc;
32#[cfg(target_arch = "wasm32")]
34pub mod web_upload;
35
36pub fn format_bytes(bytes: i64) -> String {
41 const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
42 let mut size = bytes as f64;
43 let mut unit = 0;
44 while size.abs() >= 1024.0 && unit < UNITS.len() - 1 {
45 size /= 1024.0;
46 unit += 1;
47 }
48 if unit == 0 {
49 format!("{} B", bytes)
50 } else {
51 format!("{size:.1} {}", UNITS[unit])
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::format_bytes;
58
59 #[test]
60 fn bytes_under_1k_render_as_integer() {
61 assert_eq!(format_bytes(0), "0 B");
62 assert_eq!(format_bytes(512), "512 B");
63 assert_eq!(format_bytes(1023), "1023 B");
64 }
65
66 #[test]
67 fn kilo_and_mega_render_with_one_decimal() {
68 assert_eq!(format_bytes(1536), "1.5 KB");
69 assert_eq!(format_bytes(1_258_291), "1.2 MB");
70 }
71
72 #[test]
73 fn giga_and_tera_render_with_one_decimal() {
74 assert_eq!(format_bytes(2 * 1024 * 1024 * 1024), "2.0 GB");
75 assert_eq!(format_bytes(3 * 1024_i64.pow(4)), "3.0 TB");
76 }
77
78 #[test]
79 fn values_stop_at_tb() {
80 assert_eq!(format_bytes(2048 * 1024_i64.pow(4)), "2048.0 TB");
82 }
83}