Skip to content

Commit 3d0f731

Browse files
authored
[common] Implement human-readable Display for ByteCount (#1171)
1 parent 35521af commit 3d0f731

File tree

1 file changed

+56
-7
lines changed

1 file changed

+56
-7
lines changed

common/src/api/external/mod.rs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -336,33 +336,58 @@ impl JsonSchema for RoleName {
336336
#[derive(Copy, Clone, Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
337337
pub struct ByteCount(u64);
338338

339+
#[allow(non_upper_case_globals)]
340+
const KiB: u64 = 1024;
341+
#[allow(non_upper_case_globals)]
342+
const MiB: u64 = KiB * 1024;
343+
#[allow(non_upper_case_globals)]
344+
const GiB: u64 = MiB * 1024;
345+
#[allow(non_upper_case_globals)]
346+
const TiB: u64 = GiB * 1024;
347+
339348
impl ByteCount {
340349
pub fn from_kibibytes_u32(kibibytes: u32) -> ByteCount {
341-
ByteCount::try_from(1024 * u64::from(kibibytes)).unwrap()
350+
ByteCount::try_from(KiB * u64::from(kibibytes)).unwrap()
342351
}
343352

344353
pub fn from_mebibytes_u32(mebibytes: u32) -> ByteCount {
345-
ByteCount::try_from(1024 * 1024 * u64::from(mebibytes)).unwrap()
354+
ByteCount::try_from(MiB * u64::from(mebibytes)).unwrap()
346355
}
347356

348357
pub fn from_gibibytes_u32(gibibytes: u32) -> ByteCount {
349-
ByteCount::try_from(1024 * 1024 * 1024 * u64::from(gibibytes)).unwrap()
358+
ByteCount::try_from(GiB * u64::from(gibibytes)).unwrap()
350359
}
351360

352361
pub fn to_bytes(&self) -> u64 {
353362
self.0
354363
}
355364
pub fn to_whole_kibibytes(&self) -> u64 {
356-
self.to_bytes() / 1024
365+
self.to_bytes() / KiB
357366
}
358367
pub fn to_whole_mebibytes(&self) -> u64 {
359-
self.to_bytes() / 1024 / 1024
368+
self.to_bytes() / MiB
360369
}
361370
pub fn to_whole_gibibytes(&self) -> u64 {
362-
self.to_bytes() / 1024 / 1024 / 1024
371+
self.to_bytes() / GiB
363372
}
364373
pub fn to_whole_tebibytes(&self) -> u64 {
365-
self.to_bytes() / 1024 / 1024 / 1024 / 1024
374+
self.to_bytes() / TiB
375+
}
376+
}
377+
378+
impl Display for ByteCount {
379+
fn fmt(&self, f: &mut Formatter<'_>) -> FormatResult {
380+
if self.to_bytes() >= TiB && self.to_bytes() % TiB == 0 {
381+
write!(f, "{} TiB", self.to_whole_tebibytes())
382+
} else if self.to_bytes() >= GiB && self.to_bytes() % GiB == 0 {
383+
write!(f, "{} GiB", self.to_whole_gibibytes())
384+
} else if self.to_bytes() >= MiB && self.to_bytes() % MiB == 0 {
385+
write!(f, "{} MiB", self.to_whole_mebibytes())
386+
} else if self.to_bytes() >= KiB && self.to_bytes() % KiB == 0 {
387+
write!(f, "{} KiB", self.to_whole_kibibytes())
388+
} else {
389+
write!(f, "{} B", self.to_bytes())
390+
}
366391
}
367392
}
368393

@@ -2083,6 +2108,30 @@ mod test {
20832108
assert_eq!(3, tib3.to_whole_tebibytes());
20842109
}
20852110

2111+
#[test]
2112+
fn test_bytecount_display() {
2113+
assert_eq!(format!("{}", ByteCount::from(0u32)), "0 B".to_string());
2114+
assert_eq!(format!("{}", ByteCount::from(1023)), "1023 B".to_string());
2115+
assert_eq!(format!("{}", ByteCount::from(1024)), "1 KiB".to_string());
2116+
assert_eq!(format!("{}", ByteCount::from(1025)), "1025 B".to_string());
2117+
assert_eq!(
2118+
format!("{}", ByteCount::from(1024 * 100)),
2119+
"100 KiB".to_string()
2120+
);
2121+
assert_eq!(
2122+
format!("{}", ByteCount::from_mebibytes_u32(1)),
2123+
"1 MiB".to_string()
2124+
);
2125+
assert_eq!(
2126+
format!("{}", ByteCount::from_gibibytes_u32(1)),
2127+
"1 GiB".to_string()
2128+
);
2129+
assert_eq!(
2130+
format!("{}", ByteCount::from_gibibytes_u32(1024)),
2131+
"1 TiB".to_string()
2132+
);
2133+
}
2134+
20862135
#[test]
20872136
fn test_ip_port_range_from_str() {
20882137
assert_eq!(

0 commit comments

Comments
 (0)