[pbs-devel] [RFC proxmox-backup v2 3/4] HumanByte: use u64 instead of f64 to store size
Dietmar Maurer
dietmar at proxmox.com
Wed Nov 17 14:37:19 CET 2021
Signed-off-by: Dietmar Maurer <dietmar at proxmox.com>
---
pbs-api-types/src/human_byte.rs | 84 ++++++++++++++++-----------------
1 file changed, 42 insertions(+), 42 deletions(-)
diff --git a/pbs-api-types/src/human_byte.rs b/pbs-api-types/src/human_byte.rs
index df90d446..4d8c4f21 100644
--- a/pbs-api-types/src/human_byte.rs
+++ b/pbs-api-types/src/human_byte.rs
@@ -26,22 +26,22 @@ pub enum SizeUnit {
}
impl SizeUnit {
- pub fn factor(&self) -> f64 {
+ pub fn factor(&self) -> u64 {
match self {
- SizeUnit::None => 1.0,
- SizeUnit::Byte => 1.0,
-
- SizeUnit::Kilo | SizeUnit::KByte => 1_000.0,
- SizeUnit::Mega | SizeUnit::MByte => 1_000_000.0,
- SizeUnit::Giga | SizeUnit::GByte => 1_000_000_000.0,
- SizeUnit::Tera | SizeUnit::TByte => 1_000_000_000_000.0,
- SizeUnit::Peta | SizeUnit::PByte => 1_000_000_000_000_000.0,
-
- SizeUnit::Kibi => 1024.0,
- SizeUnit::Mebi => 1024.0*1024.0,
- SizeUnit::Gibi => 1024.0*1024.0*1024.0,
- SizeUnit::Tebi => 1024.0*1024.0*1024.0*1024.0,
- SizeUnit::Pebi => 1024.0*1024.0*1024.0*1024.0*1024.0,
+ SizeUnit::None => 1,
+ SizeUnit::Byte => 1,
+
+ SizeUnit::Kilo | SizeUnit::KByte => 1_000,
+ SizeUnit::Mega | SizeUnit::MByte => 1_000_000,
+ SizeUnit::Giga | SizeUnit::GByte => 1_000_000_000,
+ SizeUnit::Tera | SizeUnit::TByte => 1_000_000_000_000,
+ SizeUnit::Peta | SizeUnit::PByte => 1_000_000_000_000_000,
+
+ SizeUnit::Kibi => 1024,
+ SizeUnit::Mebi => 1024*1024,
+ SizeUnit::Gibi => 1024*1024*1024,
+ SizeUnit::Tebi => 1024*1024*1024*1024,
+ SizeUnit::Pebi => 1024*1024*1024*1024*1024,
}
}
@@ -122,7 +122,7 @@ fn strip_unit(v: &str) -> (&str, SizeUnit) {
#[derive(Debug, Copy, Clone, UpdaterType)]
/// Byte size with unit
pub struct HumanByte {
- size: f64,
+ size: u64,
unit: SizeUnit,
}
@@ -144,12 +144,12 @@ impl ApiType for HumanByte {
impl HumanByte {
pub fn new_decimal(size: u64) -> Self {
- let this = HumanByte { size: size as f64, unit: SizeUnit::None };
+ let this = HumanByte { size: size, unit: SizeUnit::None };
this.auto_unit_decimal()
}
pub fn new_binary(size: u64) -> Self {
- let this = HumanByte { size: size as f64, unit: SizeUnit::None };
+ let this = HumanByte { size: size, unit: SizeUnit::None };
this.auto_unit_binary()
}
@@ -178,15 +178,15 @@ impl HumanByte {
}
pub fn auto_unit_decimal(mut self) -> Self {
- self.unit = if self.size >= 1_000_000_000_000_000.0 {
+ self.unit = if self.size >= 1_000_000_000_000_000 {
SizeUnit::PByte
- } else if self.size >= 1_000_000_000_000.0 {
+ } else if self.size >= 1_000_000_000_000 {
SizeUnit::TByte
- } else if self.size >= 1_000_000_000.0 {
+ } else if self.size >= 1_000_000_000 {
SizeUnit::GByte
- } else if self.size >= 1_000_000.0 {
+ } else if self.size >= 1_000_000 {
SizeUnit::MByte
- } else if self.size >= 1_000.0 {
+ } else if self.size >= 1_000 {
SizeUnit::KByte
} else {
SizeUnit::None
@@ -201,7 +201,7 @@ impl std::fmt::Display for HumanByte {
let unit = self.unit;
- let size = size/unit.factor();
+ let size = (size as f64)/(unit.factor() as f64);
let unit_str = unit.unit_str();
if unit == SizeUnit::Byte || unit == SizeUnit::None {
@@ -237,9 +237,9 @@ impl FromStr for HumanByte {
bail!("size may not be negative");
}
- let size = size*unit.factor();
+ let size = (size*(unit.factor() as f64)) as u64;
- Ok(Self { size: size, unit })
+ Ok(Self { size, unit })
}
}
@@ -252,7 +252,7 @@ fn test_human_byte_parser() -> Result<(), Error> {
assert!("-10".parse::<HumanByte>().is_err()); // negative size
- fn test(v: &str, size: f64, unit: SizeUnit, as_str: &str) -> Result<(), Error> {
+ fn test(v: &str, size: u64, unit: SizeUnit, as_str: &str) -> Result<(), Error> {
let h: HumanByte = v.parse()?;
if h.size != size {
@@ -271,29 +271,29 @@ fn test_human_byte_parser() -> Result<(), Error> {
Ok(())
}
- test("14.4", 14.4, SizeUnit::None, "14")?;
+ test("14.4", 14, SizeUnit::None, "14")?;
- test("14", 14.0, SizeUnit::None, "14")?;
- test("987654321", 987654321.0, SizeUnit::None, "987654321")?;
+ test("14", 14, SizeUnit::None, "14")?;
+ test("987654321", 987654321, SizeUnit::None, "987654321")?;
- test("1300b", 1300.0, SizeUnit::Byte, "1300 B")?;
- test("1300B", 1300.0, SizeUnit::Byte, "1300 B")?;
+ test("1300b", 1300, SizeUnit::Byte, "1300 B")?;
+ test("1300B", 1300, SizeUnit::Byte, "1300 B")?;
- test("1.5KB", 1500.0, SizeUnit::KByte, "1.5 KB")?;
- test("1.5kb", 1500.0, SizeUnit::KByte, "1.5 KB")?;
- test("1.654321MB", 1_654_321.0, SizeUnit::MByte, "1.654 MB")?;
+ test("1.5KB", 1500, SizeUnit::KByte, "1.5 KB")?;
+ test("1.5kb", 1500, SizeUnit::KByte, "1.5 KB")?;
+ test("1.654321MB", 1_654_321, SizeUnit::MByte, "1.654 MB")?;
- test("2.0GB", 2_000_000_000.0, SizeUnit::GByte, "2 GB")?;
+ test("2.0GB", 2_000_000_000, SizeUnit::GByte, "2 GB")?;
- test("1.4TB", 1_400_000_000_000.0, SizeUnit::TByte, "1.4 TB")?;
- test("1.4tb", 1_400_000_000_000.0, SizeUnit::TByte, "1.4 TB")?;
+ test("1.4TB", 1_400_000_000_000, SizeUnit::TByte, "1.4 TB")?;
+ test("1.4tb", 1_400_000_000_000, SizeUnit::TByte, "1.4 TB")?;
- test("2KiB", 2048.0, SizeUnit::Kibi, "2 KiB")?;
- test("2kib", 2048.0, SizeUnit::Kibi, "2 KiB")?;
+ test("2KiB", 2048, SizeUnit::Kibi, "2 KiB")?;
+ test("2kib", 2048, SizeUnit::Kibi, "2 KiB")?;
- test("2.3456MiB", 2.3456*1024.0*1024.0, SizeUnit::Mebi, "2.345 MiB")?;
+ test("2.3456MiB", (2.3456*1024.0*1024.0) as u64, SizeUnit::Mebi, "2.345 MiB")?;
- test("4gib", 4.0*1024.0*1024.0*1024.0, SizeUnit::Gibi, "4 GiB")?;
+ test("4gib", (4.0*1024.0*1024.0*1024.0) as u64, SizeUnit::Gibi, "4 GiB")?;
Ok(())
}
--
2.30.2
More information about the pbs-devel
mailing list