From 837b550238aa671a591ccf282dddeab29cadb206 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:42 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/bytesize/.cargo-checksum.json | 2 +- vendor/bytesize/Cargo.toml | 35 ++++-- vendor/bytesize/README.md | 38 +++++- vendor/bytesize/src/lib.rs | 204 +++++++++++++++++++++++++------- vendor/bytesize/src/parse.rs | 218 +++++++++++++++++++++++++++++++++++ 5 files changed, 446 insertions(+), 51 deletions(-) create mode 100644 vendor/bytesize/src/parse.rs (limited to 'vendor/bytesize') diff --git a/vendor/bytesize/.cargo-checksum.json b/vendor/bytesize/.cargo-checksum.json index 654da467e..c8c9e3f95 100644 --- a/vendor/bytesize/.cargo-checksum.json +++ b/vendor/bytesize/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"151e2d4b44c05fa3c40d21ca163c954c53592db56153c039c128f0ebd9bfbe79","LICENSE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","README.md":"f0716240034443c0407f8e1e9f88c6db76ad7f41273de491bbc03743ca1cb5b8","src/lib.rs":"14bfe436ff5a786d718b9f60e5b6428a5899bfa97a307814b0973ce5320fc59e"},"package":"81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"} \ No newline at end of file +{"files":{"Cargo.toml":"edf0f31ce8a53b46c1fa632fded9f6a9bd94c75505fec7470e02c9e7afb60679","LICENSE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","README.md":"d0deb99fef48f13ec4439888a677c4f2c46cc92ba35eebf8cf53ded962852c7f","src/lib.rs":"f6c4d6e4788dba33a992750947f72999b3e0b418bfa3f425229e60fe35952ffc","src/parse.rs":"7b8287d5cda2b7e001c8deb8eee68d8e5b9753d0cfd30ccec480382a1eebf0de"},"package":"38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5"} \ No newline at end of file diff --git a/vendor/bytesize/Cargo.toml b/vendor/bytesize/Cargo.toml index 5265e11b9..475fef195 100644 --- a/vendor/bytesize/Cargo.toml +++ b/vendor/bytesize/Cargo.toml @@ -3,25 +3,44 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] name = "bytesize" -version = "1.0.1" +version = "1.2.0" authors = ["Hyunsik Choi "] description = "an utility for human-readable bytes representations" homepage = "https://github.com/hyunsik/bytesize/" documentation = "https://docs.rs/bytesize/" readme = "README.md" -keywords = ["byte", "byte-size", "utility", "human-readable", "format"] +keywords = [ + "byte", + "byte-size", + "utility", + "human-readable", + "format", +] license = "Apache-2.0" repository = "https://github.com/hyunsik/bytesize/" + [dependencies.serde] version = "1.0" -features = ["derive"] optional = true + +[dev-dependencies.serde] +version = "1.0" +features = ["derive"] + +[dev-dependencies.serde_json] +version = "1.0" + +[dev-dependencies.toml] +version = "0.5" + +[features] +default = [] +serde = ["dep:serde"] diff --git a/vendor/bytesize/README.md b/vendor/bytesize/README.md index 9c3464d0e..3db9c8307 100644 --- a/vendor/bytesize/README.md +++ b/vendor/bytesize/README.md @@ -5,6 +5,12 @@ ByteSize is an utility for human-readable byte count representation. +Features: +* Pre-defined constants for various size units (e.g., B, Kb, kib, Mb, Mib, Gb, Gib, ... PB) +* `ByteSize` type which presents size units convertible to different size units. +* Artimetic operations for `ByteSize` +* FromStr impl for `ByteSize`, allowing to parse from string size representations like 1.5KiB and 521TiB. + [API Documentation](https://docs.rs/bytesize/) ## Usage @@ -13,7 +19,7 @@ Add this to your Cargo.toml: ```toml [dependencies] -bytesize = "1.0.0" +bytesize = {version = "1.1.0", features = ["serde"]} ``` and this to your crate root: @@ -49,7 +55,7 @@ fn assert_display(expected: &str, b: ByteSize) { fn test_to_string() { assert_to_string("215 B", ByteSize(215), true); assert_to_string("215 B", ByteSize(215), false); - + assert_to_string("215 B", ByteSize::b(215), true); assert_to_string("215 B", ByteSize::b(215), false); @@ -73,7 +79,33 @@ fn assert_display(expected: &str, b: ByteSize) { assert_to_string("540.9 PiB", ByteSize::pb(609), true); assert_to_string("609.0 PB", ByteSize::pb(609), false); -} + } + + #[test] + fn test_parsing_from_str() { + // shortcut for writing test cases + fn parse(s: &str) -> u64 { + s.parse::().unwrap().0 + } + + assert_eq!("0".parse::().unwrap().0, 0); + assert_eq!(parse("0"), 0); + assert_eq!(parse("500"), 500); + assert_eq!(parse("1K"), Unit::KiloByte * 1); + assert_eq!(parse("1Ki"), Unit::KibiByte * 1); + assert_eq!(parse("1.5Ki"), (1.5 * Unit::KibiByte) as u64); + assert_eq!(parse("1KiB"), 1 * Unit::KibiByte); + assert_eq!(parse("1.5KiB"), (1.5 * Unit::KibiByte) as u64); + assert_eq!(parse("3 MB"), Unit::MegaByte * 3); + assert_eq!(parse("4 MiB"), Unit::MebiByte * 4); + assert_eq!(parse("6 GB"), 6 * Unit::GigaByte); + assert_eq!(parse("4 GiB"), 4 * Unit::GibiByte); + assert_eq!(parse("88TB"), 88 * Unit::TeraByte); + assert_eq!(parse("521TiB"), 521 * Unit::TebiByte); + assert_eq!(parse("8 PB"), 8 * Unit::PetaByte); + assert_eq!(parse("8P"), 8 * Unit::PetaByte); + assert_eq!(parse("12 PiB"), 12 * Unit::PebiByte); + } ``` ### Arithmetic operations diff --git a/vendor/bytesize/src/lib.rs b/vendor/bytesize/src/lib.rs index e2d63c9c5..01c4440e5 100644 --- a/vendor/bytesize/src/lib.rs +++ b/vendor/bytesize/src/lib.rs @@ -27,12 +27,17 @@ //! assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false)); //! ``` +mod parse; + #[cfg(feature = "serde")] -#[macro_use] extern crate serde; +#[cfg(feature = "serde")] +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "serde")] +use std::convert::TryFrom; -use std::fmt::{Debug, Display, Formatter, Result}; -use std::ops::{Add, Mul}; +use std::fmt::{self, Debug, Display, Formatter}; +use std::ops::{Add, AddAssign, Mul, MulAssign}; /// byte size for 1 byte pub const B: u64 = 1; @@ -58,8 +63,8 @@ pub const TIB: u64 = 1_099_511_627_776; /// bytes size for 1 pebibyte pub const PIB: u64 = 1_125_899_906_842_624; -static UNITS: &'static str = "KMGTPE"; -static UNITS_SI: &'static str = "kMGTPE"; +static UNITS: &str = "KMGTPE"; +static UNITS_SI: &str = "kMGTPE"; static LN_KB: f64 = 6.931471806; // ln 1024 static LN_KIB: f64 = 6.907755279; // ln 1000 @@ -104,68 +109,67 @@ pub fn pib>(size: V) -> u64 { } /// Byte size representation -#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)] pub struct ByteSize(pub u64); impl ByteSize { #[inline(always)] - pub fn b(size: u64) -> ByteSize { + pub const fn b(size: u64) -> ByteSize { ByteSize(size) } #[inline(always)] - pub fn kb(size: u64) -> ByteSize { + pub const fn kb(size: u64) -> ByteSize { ByteSize(size * KB) } #[inline(always)] - pub fn kib(size: u64) -> ByteSize { + pub const fn kib(size: u64) -> ByteSize { ByteSize(size * KIB) } #[inline(always)] - pub fn mb(size: u64) -> ByteSize { + pub const fn mb(size: u64) -> ByteSize { ByteSize(size * MB) } #[inline(always)] - pub fn mib(size: u64) -> ByteSize { + pub const fn mib(size: u64) -> ByteSize { ByteSize(size * MIB) } #[inline(always)] - pub fn gb(size: u64) -> ByteSize { + pub const fn gb(size: u64) -> ByteSize { ByteSize(size * GB) } #[inline(always)] - pub fn gib(size: u64) -> ByteSize { + pub const fn gib(size: u64) -> ByteSize { ByteSize(size * GIB) } #[inline(always)] - pub fn tb(size: u64) -> ByteSize { + pub const fn tb(size: u64) -> ByteSize { ByteSize(size * TB) } #[inline(always)] - pub fn tib(size: u64) -> ByteSize { + pub const fn tib(size: u64) -> ByteSize { ByteSize(size * TIB) } #[inline(always)] - pub fn pb(size: u64) -> ByteSize { + pub const fn pb(size: u64) -> ByteSize { ByteSize(size * PB) } #[inline(always)] - pub fn pib(size: u64) -> ByteSize { + pub const fn pib(size: u64) -> ByteSize { ByteSize(size * PIB) } #[inline(always)] - pub fn as_u64(&self) -> u64 { + pub const fn as_u64(&self) -> u64 { self.0 } @@ -204,27 +208,19 @@ pub fn to_string(bytes: u64, si_prefix: bool) -> String { } impl Display for ByteSize { - fn fmt(&self, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) ->fmt::Result { f.pad(&to_string(self.0, false)) } } impl Debug for ByteSize { - fn fmt(&self, f: &mut Formatter) -> Result { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{}", self) } } macro_rules! commutative_op { ($t:ty) => { - impl Add<$t> for ByteSize { - type Output = ByteSize; - #[inline(always)] - fn add(self, rhs: $t) -> ByteSize { - ByteSize(self.0 + (rhs as u64)) - } - } - impl Add for $t { type Output = ByteSize; #[inline(always)] @@ -233,14 +229,6 @@ macro_rules! commutative_op { } } - impl Mul<$t> for ByteSize { - type Output = ByteSize; - #[inline(always)] - fn mul(self, rhs: $t) -> ByteSize { - ByteSize(self.0 * (rhs as u64)) - } - } - impl Mul for $t { type Output = ByteSize; #[inline(always)] @@ -265,13 +253,118 @@ impl Add for ByteSize { } } +impl AddAssign for ByteSize { + #[inline(always)] + fn add_assign(&mut self, rhs: ByteSize) { + self.0 += rhs.0 + } +} + +impl Add for ByteSize + where T: Into { + type Output = ByteSize; + #[inline(always)] + fn add(self, rhs: T) -> ByteSize { + ByteSize(self.0 + (rhs.into() as u64)) + } +} + +impl AddAssign for ByteSize + where T: Into { + #[inline(always)] + fn add_assign(&mut self, rhs: T) { + self.0 += rhs.into() as u64; + } +} + +impl Mul for ByteSize + where T: Into { + type Output = ByteSize; + #[inline(always)] + fn mul(self, rhs: T) -> ByteSize { + ByteSize(self.0 * (rhs.into() as u64)) + } +} + +impl MulAssign for ByteSize + where T: Into { + #[inline(always)] + fn mul_assign(&mut self, rhs: T) { + self.0 *= rhs.into() as u64; + } +} + +#[cfg(feature = "serde")] +impl<'de> Deserialize<'de> for ByteSize { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ByteSizeVistor; + + impl<'de> de::Visitor<'de> for ByteSizeVistor { + type Value = ByteSize; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("an integer or string") + } + + fn visit_i64(self, value: i64) -> Result { + if let Ok(val) = u64::try_from(value) { + Ok(ByteSize(val)) + } else { + Err(E::invalid_value( + de::Unexpected::Signed(value), + &"integer overflow", + )) + } + } + + fn visit_u64(self, value: u64) -> Result { + Ok(ByteSize(value)) + } + + fn visit_str(self, value: &str) -> Result { + if let Ok(val) = value.parse() { + Ok(val) + } else { + Err(E::invalid_value( + de::Unexpected::Str(value), + &"parsable string", + )) + } + } + } + + if deserializer.is_human_readable() { + deserializer.deserialize_any(ByteSizeVistor) + } else { + deserializer.deserialize_u64(ByteSizeVistor) + } + } +} + +#[cfg(feature = "serde")] +impl Serialize for ByteSize { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + if serializer.is_human_readable() { + ::serialize(self.to_string().as_str(), serializer) + } else { + self.0.serialize(serializer) + } + } +} + #[cfg(test)] mod tests { use super::*; #[test] fn test_arithmetic_op() { - let x = ByteSize::mb(1); + let mut x = ByteSize::mb(1); let y = ByteSize::kb(100); assert_eq!((x + y).as_u64(), 1_100_000u64); @@ -279,11 +372,16 @@ mod tests { assert_eq!((x + (100 * 1000) as u64).as_u64(), 1_100_000); assert_eq!((x * 2u64).as_u64(), 2_000_000); + + x += y; + assert_eq!(x.as_u64(), 1_100_000); + x *= 2u64; + assert_eq!(x.as_u64(), 2_200_000); } #[test] fn test_arithmetic_primitives() { - let x = ByteSize::mb(1); + let mut x = ByteSize::mb(1); assert_eq!((x + MB as u64).as_u64(), 2_000_000); @@ -292,6 +390,12 @@ mod tests { assert_eq!((x + KB as u16).as_u64(), 1_001_000); assert_eq!((x + B as u8).as_u64(), 1_000_001); + + x += MB as u64; + x += MB as u32; + x += 10u16; + x += 1u8; + assert_eq!(x.as_u64(), 3_000_011); } #[test] @@ -374,4 +478,26 @@ mod tests { fn test_to_string() { assert_to_string("609.0 PB", ByteSize::pb(609), false); } + + #[cfg(feature = "serde")] + #[test] + fn test_serde() { + #[derive(Serialize, Deserialize)] + struct S { + x: ByteSize, + } + + let s: S = serde_json::from_str(r#"{ "x": "5 B" }"#).unwrap(); + assert_eq!(s.x, ByteSize(5)); + + let s: S = serde_json::from_str(r#"{ "x": 1048576 }"#).unwrap(); + assert_eq!(s.x, "1 MiB".parse::().unwrap()); + + let s: S = toml::from_str(r#"x = "2.5 MiB""#).unwrap(); + assert_eq!(s.x, "2.5 MiB".parse::().unwrap()); + + // i64 MAX + let s: S = toml::from_str(r#"x = "9223372036854775807""#).unwrap(); + assert_eq!(s.x, "9223372036854775807".parse::().unwrap()); + } } diff --git a/vendor/bytesize/src/parse.rs b/vendor/bytesize/src/parse.rs new file mode 100644 index 000000000..e86034e2f --- /dev/null +++ b/vendor/bytesize/src/parse.rs @@ -0,0 +1,218 @@ +use super::ByteSize; + +impl std::str::FromStr for ByteSize { + type Err = String; + + fn from_str(value: &str) -> Result { + if let Ok(v) = value.parse::() { + return Ok(Self(v)); + } + let number: String = value + .chars() + .take_while(|c| c.is_ascii_digit() || c == &'.') + .collect(); + match number.parse::() { + Ok(v) => { + let suffix: String = value + .chars() + .skip_while(|c| c.is_whitespace() || c.is_ascii_digit() || c == &'.') + .collect(); + match suffix.parse::() { + Ok(u) => Ok(Self((v * u) as u64)), + Err(error) => Err(format!( + "couldn't parse {:?} into a known SI unit, {}", + suffix, error + )), + } + } + Err(error) => Err(format!( + "couldn't parse {:?} into a ByteSize, {}", + value, error + )), + } + } +} + +enum Unit { + Byte, + // power of tens + KiloByte, + MegaByte, + GigaByte, + TeraByte, + PetaByte, + // power of twos + KibiByte, + MebiByte, + GibiByte, + TebiByte, + PebiByte, +} + +impl Unit { + fn factor(&self) -> u64 { + match self { + Self::Byte => super::B, + // power of tens + Self::KiloByte => super::KB, + Self::MegaByte => super::MB, + Self::GigaByte => super::GB, + Self::TeraByte => super::TB, + Self::PetaByte => super::PB, + // power of twos + Self::KibiByte => super::KIB, + Self::MebiByte => super::MIB, + Self::GibiByte => super::GIB, + Self::TebiByte => super::TIB, + Self::PebiByte => super::PIB, + } + } +} + +mod impl_ops { + use super::Unit; + use std::ops; + + impl ops::Add for Unit { + type Output = u64; + + fn add(self, other: u64) -> Self::Output { + self.factor() + other + } + } + + impl ops::Add for u64 { + type Output = u64; + + fn add(self, other: Unit) -> Self::Output { + self + other.factor() + } + } + + impl ops::Mul for Unit { + type Output = u64; + + fn mul(self, other: u64) -> Self::Output { + self.factor() * other + } + } + + impl ops::Mul for u64 { + type Output = u64; + + fn mul(self, other: Unit) -> Self::Output { + self * other.factor() + } + } + + impl ops::Add for Unit { + type Output = f64; + + fn add(self, other: f64) -> Self::Output { + self.factor() as f64 + other + } + } + + impl ops::Add for f64 { + type Output = f64; + + fn add(self, other: Unit) -> Self::Output { + other.factor() as f64 + self + } + } + + impl ops::Mul for Unit { + type Output = f64; + + fn mul(self, other: f64) -> Self::Output { + self.factor() as f64 * other + } + } + + impl ops::Mul for f64 { + type Output = f64; + + fn mul(self, other: Unit) -> Self::Output { + other.factor() as f64 * self + } + } +} + +impl std::str::FromStr for Unit { + type Err = String; + + fn from_str(unit: &str) -> Result { + match unit.to_lowercase().as_str() { + "b" => Ok(Self::Byte), + // power of tens + "k" | "kb" => Ok(Self::KiloByte), + "m" | "mb" => Ok(Self::MegaByte), + "g" | "gb" => Ok(Self::GigaByte), + "t" | "tb" => Ok(Self::TeraByte), + "p" | "pb" => Ok(Self::PetaByte), + // power of twos + "ki" | "kib" => Ok(Self::KibiByte), + "mi" | "mib" => Ok(Self::MebiByte), + "gi" | "gib" => Ok(Self::GibiByte), + "ti" | "tib" => Ok(Self::TebiByte), + "pi" | "pib" => Ok(Self::PebiByte), + _ => Err(format!("couldn't parse unit of {:?}", unit)), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn when_ok() { + // shortcut for writing test cases + fn parse(s: &str) -> u64 { + s.parse::().unwrap().0 + } + + assert_eq!("0".parse::().unwrap().0, 0); + assert_eq!(parse("0"), 0); + assert_eq!(parse("500"), 500); + assert_eq!(parse("1K"), Unit::KiloByte * 1); + assert_eq!(parse("1Ki"), Unit::KibiByte * 1); + assert_eq!(parse("1.5Ki"), (1.5 * Unit::KibiByte) as u64); + assert_eq!(parse("1KiB"), 1 * Unit::KibiByte); + assert_eq!(parse("1.5KiB"), (1.5 * Unit::KibiByte) as u64); + assert_eq!(parse("3 MB"), Unit::MegaByte * 3); + assert_eq!(parse("4 MiB"), Unit::MebiByte * 4); + assert_eq!(parse("6 GB"), 6 * Unit::GigaByte); + assert_eq!(parse("4 GiB"), 4 * Unit::GibiByte); + assert_eq!(parse("88TB"), 88 * Unit::TeraByte); + assert_eq!(parse("521TiB"), 521 * Unit::TebiByte); + assert_eq!(parse("8 PB"), 8 * Unit::PetaByte); + assert_eq!(parse("8P"), 8 * Unit::PetaByte); + assert_eq!(parse("12 PiB"), 12 * Unit::PebiByte); + } + + #[test] + fn when_err() { + // shortcut for writing test cases + fn parse(s: &str) -> Result { + s.parse::() + } + + assert!(parse("").is_err()); + assert!(parse("a124GB").is_err()); + } + + #[test] + fn to_and_from_str() { + // shortcut for writing test cases + fn parse(s: &str) -> u64 { + s.parse::().unwrap().0 + } + + assert_eq!(parse(&format!("{}", parse("128GB"))), 128 * Unit::GigaByte); + assert_eq!( + parse(&crate::to_string(parse("128.000 GiB"), true)), + 128 * Unit::GibiByte + ); + } +} -- cgit v1.2.3