o1vm/utils.rs
1const KUNIT: usize = 1024; // a kunit of memory is 1024 things (bytes, kilobytes, ...)
2const PREFIXES: &str = "KMGTPE"; // prefixes for memory quantities KiB, MiB, GiB, ...
3
4// Create a human-readable string representation of the memory size
5pub fn memory_size(total: usize) -> String {
6 if total < KUNIT {
7 format!("{total} B")
8 } else {
9 // Compute the index in the prefixes string above
10 let mut idx = 0;
11 let mut d = KUNIT;
12 let mut n = total / KUNIT;
13
14 while n >= KUNIT {
15 d *= KUNIT;
16 idx += 1;
17 n /= KUNIT;
18 }
19
20 let value = total as f64 / d as f64;
21
22 let prefix =
23 ////////////////////////////////////////////////////////////////////////
24 // Famous last words: 1023 exabytes ought to be enough for anybody //
25 // //
26 // Corollary: //
27 // unwrap() below shouldn't fail //
28 // The maximum representation for usize corresponds to 16 exabytes //
29 // anyway //
30 ////////////////////////////////////////////////////////////////////////
31 PREFIXES.chars().nth(idx).unwrap();
32
33 format!("{:.1} {}iB", value, prefix)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39
40 use super::*;
41
42 #[test]
43 fn test_memory_size() {
44 assert_eq!(memory_size(1023_usize), "1023 B");
45 assert_eq!(memory_size(1024_usize), "1.0 KiB");
46 assert_eq!(memory_size(1024 * 1024_usize), "1.0 MiB");
47 assert_eq!(memory_size(2100 * 1024 * 1024_usize), "2.1 GiB");
48 assert_eq!(memory_size(usize::MAX), "16.0 EiB");
49 }
50}