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