net_bytes/
lib.rs

1mod download_acceleration;
2mod download_speed;
3mod file_size;
4
5use std::fmt::{self, Display};
6
7use rust_decimal::Decimal;
8
9pub use download_acceleration::DownloadAcceleration;
10pub use download_speed::DownloadSpeed;
11pub use file_size::{FileSize, NonZeroFileSize};
12
13pub use rust_decimal;
14
15/// A trait for types that can be formatted as file sizes
16///
17/// 可以格式化为文件大小的 trait
18pub trait FileSizeFormat {
19    /// Returns the formatted value and unit in SI (base-1000) standard
20    ///
21    /// 返回 SI (base-1000) 标准的 (formatted_value, unit)
22    fn get_si_parts(&self) -> (String, &'static str);
23
24    /// Returns the formatted value and unit in IEC (base-1024) standard
25    ///
26    /// 返回 IEC (base-1024) 标准的 (formatted_value, unit)
27    fn get_iec_parts(&self) -> (String, &'static str);
28
29    /// Returns a formatted string in SI (base-1000) standard
30    ///
31    /// 返回 SI (base-1000) 标准的格式化字符串
32    #[inline]
33    fn to_si_string(&self) -> String {
34        let (value, unit) = self.get_si_parts();
35        format!("{} {}", value, unit)
36    }
37
38    /// Returns a formatted string in IEC (base-1024) standard
39    ///
40    /// 返回 IEC (base-1024) 标准的格式化字符串
41    #[inline]
42    fn to_iec_string(&self) -> String {
43        let (value, unit) = self.get_iec_parts();
44        format!("{} {}", value, unit)
45    }
46}
47
48pub struct FormattedValue<T: FileSizeFormat> {
49    value: T,
50    standard: SizeStandard,
51}
52
53impl<T: FileSizeFormat> FormattedValue<T> {
54    pub fn new(value: T, standard: SizeStandard) -> Self {
55        Self { value, standard }
56    }
57
58    pub fn get_value(&self) -> &T {
59        &self.value
60    }
61}
62
63impl<T: FileSizeFormat> Display for FormattedValue<T> {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        let display = match self.standard {
66            SizeStandard::SI => self.value.to_si_string(),
67            SizeStandard::IEC => self.value.to_iec_string(),
68        };
69        write!(f, "{}", display)
70    }
71}
72
73/// Standard for file size units
74///
75/// 文件大小单位标准
76#[derive(Debug, Clone, Copy)]
77pub enum SizeStandard {
78    /// SI standard (base-1000, units: KB, MB)
79    ///
80    /// SI 标准 (base-1000, 单位 KB, MB)
81    SI,
82    /// IEC standard (base-1024, units: KiB, MiB)
83    ///
84    /// IEC 标准 (base-1024, 单位 KiB, MiB)
85    IEC,
86}
87
88/// Format a numeric value and return (formatted_value, unit_index)
89///
90/// 格式化数值部分,返回 (formatted_value, unit_index)
91pub(crate) fn format_parts(
92    mut value: Decimal,
93    base: Decimal,
94    units: &'static [&'static str],
95) -> (String, &'static str) {
96    let mut unit_index = 0;
97
98    while value >= base && unit_index < units.len() - 1 {
99        value /= base;
100        unit_index += 1;
101    }
102
103    let formatted_value = format_decimal_value(value);
104    (formatted_value, units[unit_index])
105}
106
107/// Format a decimal value with automatic decimal places selection based on value
108/// - Less than 10: 2 decimal places
109/// - 10 or greater: 1 decimal place
110///
111/// 格式化十进制数值,根据值的大小自动选择小数位数
112/// - 小于10: 显示2位小数
113/// - 大于等于10: 显示1位小数
114#[inline]
115pub(crate) fn format_decimal_value(value: Decimal) -> String {
116    if value < Decimal::from(10) {
117        let mut rounded = value.round_dp(2);
118        rounded.rescale(2);
119        rounded.to_string()
120    } else {
121        let mut rounded = value.round_dp(1);
122        rounded.rescale(1);
123        rounded.to_string()
124    }
125}