1use crate::{Context, SizeOf};
2use core::fmt::{self, Display};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
6#[repr(transparent)]
7pub struct HumanBytes {
8 pub bytes: u64,
10}
11
12impl HumanBytes {
13 #[inline]
15 pub const fn new(bytes: u64) -> Self {
16 Self { bytes }
17 }
18
19 #[inline]
21 pub const fn into_inner(self) -> u64 {
22 self.bytes
23 }
24}
25
26impl From<u64> for HumanBytes {
27 #[inline]
28 fn from(bytes: u64) -> Self {
29 Self { bytes }
30 }
31}
32
33impl From<u32> for HumanBytes {
34 #[inline]
35 fn from(bytes: u32) -> Self {
36 Self {
37 bytes: bytes as u64,
38 }
39 }
40}
41
42impl From<usize> for HumanBytes {
43 #[inline]
44 fn from(bytes: usize) -> Self {
45 Self {
46 bytes: bytes as u64,
47 }
48 }
49}
50
51const KB: f64 = 1024.0;
52const MB: f64 = KB * KB;
53const GB: f64 = KB * KB * KB;
54const TB: f64 = KB * KB * KB * KB;
55const PB: f64 = KB * KB * KB * KB * KB;
56const EB: f64 = KB * KB * KB * KB * KB * KB;
57impl Display for HumanBytes {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 let bytes = self.bytes as f64;
63
64 if bytes / EB > 1.0 {
65 write!(f, "{:.02} EiB", bytes / EB)
66 } else if bytes / PB > 1.0 {
67 write!(f, "{:.02} PiB", bytes / PB)
68 } else if bytes / TB > 1.0 {
69 write!(f, "{:.02} TiB", bytes / TB)
70 } else if bytes / GB > 1.0 {
71 write!(f, "{:.02} GiB", bytes / GB)
72 } else if bytes / MB > 1.0 {
73 write!(f, "{:.02} MiB", bytes / MB)
74 } else if bytes / KB > 1.0 {
75 write!(f, "{:.02} KiB", bytes / KB)
76 } else {
77 write!(f, "{} B", self.bytes)
78 }
79 }
80}
81
82impl SizeOf for HumanBytes {
83 fn size_of_children(&self, _context: &mut Context) {}
84}