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
15pub trait FileSizeFormat {
19 fn get_si_parts(&self) -> (String, &'static str);
23
24 fn get_iec_parts(&self) -> (String, &'static str);
28
29 #[inline]
33 fn to_si_string(&self) -> String {
34 let (value, unit) = self.get_si_parts();
35 format!("{} {}", value, unit)
36 }
37
38 #[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#[derive(Debug, Clone, Copy)]
77pub enum SizeStandard {
78 SI,
82 IEC,
86}
87
88pub(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#[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}