parallel_disk_usage/bytes_format/
formatter.rs

1use super::{scale_base, ParsedValue};
2use std::fmt::Debug;
3
4/// Format a quantity of bytes.
5#[derive(Debug, Clone, Copy)]
6pub struct Formatter {
7    scale_base: u64,
8}
9
10impl Formatter {
11    /// Create a new formatter.
12    #[inline]
13    pub const fn new(scale_base: u64) -> Self {
14        Formatter { scale_base }
15    }
16
17    /// Multiplication factor.
18    #[inline]
19    pub const fn scale_base(self) -> u64 {
20        self.scale_base
21    }
22
23    /// Get scale in number.
24    #[inline]
25    pub const fn scale(self, exp: u32) -> u64 {
26        self.scale_base().pow(exp)
27    }
28
29    /// Parse a value according to the prefixing rule.
30    pub fn parse_value(self, value: u64) -> ParsedValue {
31        let float_value = value as f32;
32        macro_rules! check {
33            ($exp:literal => $unit:literal) => {{
34                let scale = self.scale($exp);
35                if value >= scale {
36                    return ParsedValue::Big {
37                        coefficient: float_value / (scale as f32),
38                        unit: $unit,
39                        exponent: $exp,
40                        scale,
41                    };
42                }
43            }};
44        }
45
46        check!(5 => 'P');
47        check!(4 => 'T');
48        check!(3 => 'G');
49        check!(2 => 'M');
50        check!(1 => 'K');
51        ParsedValue::Small {
52            value: value as u16,
53        }
54    }
55}
56
57macro_rules! variant {
58    ($(#[$attributes:meta])* $name:ident) => {
59        $(#[$attributes])*
60        pub const $name: Formatter = Formatter::new(scale_base::$name);
61    };
62}
63
64variant! {
65    /// Format a quantity of bytes in [metric system](scale_base::METRIC).
66    METRIC
67}
68
69variant! {
70    /// Format a quantity of bytes in [binary system](scale_base::BINARY).
71    BINARY
72}