Skip to main content

yggdrasil/utils/
mod.rs

1//! 通用工具函数子模块。
2//!
3//! - `comment_storage`:评论草稿 localStorage 持久化(WASM 端)。
4//! - `html`:HTML 转义(两端通用)。
5//! - `js`:WASM 端调用 `window.__init*` 可选全局函数(仅 wasm32)。
6//! - `text`:Markdown / 纯文本处理(仅 `server` feature)。
7//! - `time`:跨平台时间/睡眠工具(WASM 与原生异步版本)。
8//! - `web_upload`:multipart 文件上传 fetch 助手(仅 wasm32)。
9
10/// 评论草稿 localStorage 持久化(仅在 WASM 端实际读写)。
11pub mod comment_storage;
12/// HTML 转义工具(前端后端通用)。
13pub mod html;
14/// WASM 端 JS 全局函数调用工具(仅 wasm32 编译)。
15#[cfg(target_arch = "wasm32")]
16pub mod js;
17/// 服务端共享常量与工具(hash、正则、上限)。
18#[cfg(feature = "server")]
19pub mod server;
20/// Markdown / 纯文本处理工具。
21#[cfg(feature = "server")]
22pub mod text;
23/// 跨平台时间/睡眠工具。
24pub mod time;
25/// WASM 端 multipart 上传助手(仅 wasm32 编译)。
26#[cfg(target_arch = "wasm32")]
27pub mod web_upload;
28
29/// 字节数 → 人类可读字符串(如 `1.2 MB`)。
30///
31/// 全项目唯一实现:素材管理页、上传列表与系统管理各 tab 共用。
32/// 按 1024 进位取到 TB;不足 1 KB 时原样输出整数 B,其余保留一位小数。
33pub fn format_bytes(bytes: i64) -> String {
34    const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
35    let mut size = bytes as f64;
36    let mut unit = 0;
37    while size.abs() >= 1024.0 && unit < UNITS.len() - 1 {
38        size /= 1024.0;
39        unit += 1;
40    }
41    if unit == 0 {
42        format!("{} B", bytes)
43    } else {
44        format!("{size:.1} {}", UNITS[unit])
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::format_bytes;
51
52    #[test]
53    fn bytes_under_1k_render_as_integer() {
54        assert_eq!(format_bytes(0), "0 B");
55        assert_eq!(format_bytes(512), "512 B");
56        assert_eq!(format_bytes(1023), "1023 B");
57    }
58
59    #[test]
60    fn kilo_and_mega_render_with_one_decimal() {
61        assert_eq!(format_bytes(1536), "1.5 KB");
62        assert_eq!(format_bytes(1_258_291), "1.2 MB");
63    }
64
65    #[test]
66    fn giga_and_tera_render_with_one_decimal() {
67        assert_eq!(format_bytes(2 * 1024 * 1024 * 1024), "2.0 GB");
68        assert_eq!(format_bytes(3 * 1024_i64.pow(4)), "3.0 TB");
69    }
70
71    #[test]
72    fn values_stop_at_tb() {
73        // 超过 TB 后继续按 TB 表示,不进位到不存在的单位。
74        assert_eq!(format_bytes(2048 * 1024_i64.pow(4)), "2048.0 TB");
75    }
76}