parallel_disk_usage/
size.rs

1use super::bytes_format::{self, BytesFormat};
2use derive_more::{Add, AddAssign, From, Into, Sum};
3use std::{
4    fmt::{Debug, Display},
5    ops::{Mul, MulAssign},
6};
7
8#[cfg(feature = "json")]
9use serde::{Deserialize, Serialize};
10
11/// Types whose values can be used as disk usage statistic.
12pub trait Size:
13    Debug
14    + Default
15    + Clone
16    + Copy
17    + PartialEq
18    + Eq
19    + PartialOrd
20    + Ord
21    + Add<Output = Self>
22    + AddAssign
23    + Sum
24{
25    /// Underlying type
26    type Inner: From<Self> + Into<Self> + Mul<Self, Output = Self>;
27    /// Format to be used to [`display`](Size::display) the value.
28    type DisplayFormat: Copy;
29    /// Return type of [`display`](Size::display).
30    type DisplayOutput: Display;
31    /// Display the disk usage in a measurement system.
32    fn display(self, input: Self::DisplayFormat) -> Self::DisplayOutput;
33}
34
35macro_rules! newtype {
36    (
37        $(#[$attribute:meta])*
38        $name:ident = $inner:ty;
39        display: ($display_format:ty) -> $display_output:ty = $display_impl:expr;
40    ) => {
41        #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
42        #[derive(From, Into, Add, AddAssign, Sum)]
43        #[cfg_attr(feature = "json", derive(Deserialize, Serialize))]
44        $(#[$attribute])*
45        pub struct $name($inner);
46
47        impl $name {
48            pub const fn new(inner: $inner) -> Self {
49                $name(inner)
50            }
51
52            pub const fn inner(self) -> $inner {
53                self.0
54            }
55        }
56
57        impl Size for $name {
58            type Inner = $inner;
59            type DisplayFormat = $display_format;
60            type DisplayOutput = $display_output;
61            fn display(self, format: Self::DisplayFormat) -> Self::DisplayOutput {
62                let display: fn(Self, Self::DisplayFormat) -> Self::DisplayOutput = $display_impl;
63                display(self, format)
64            }
65        }
66
67        impl Mul<$inner> for $name {
68            type Output = Self;
69            fn mul(self, rhs: $inner) -> Self::Output {
70                self.0.mul(rhs).into()
71            }
72        }
73
74        impl Mul<$name> for $inner {
75            type Output = $name;
76            fn mul(self, rhs: $name) -> Self::Output {
77                rhs * self
78            }
79        }
80
81        impl MulAssign<$inner> for $name {
82            fn mul_assign(&mut self, rhs: $inner) {
83                self.0 *= rhs;
84            }
85        }
86    };
87}
88
89newtype!(
90    /// Number of bytes.
91    Bytes = u64;
92    display: (BytesFormat) -> bytes_format::Output = |bytes, format| {
93        format.format(bytes.into())
94    };
95);
96
97newtype!(
98    /// Number of blocks.
99    Blocks = u64;
100    display: (()) -> u64 = |blocks, ()| blocks.inner();
101);