From f934fa8f11de2cd1ce142e2947ba66015cb153cd Mon Sep 17 00:00:00 2001 From: Christian Krause Date: Wed, 2 Jan 2019 11:53:25 +0100 Subject: [PATCH 1/4] fixes article usage it's "a utility", not "an ...", because the pronunciation of "utility" starts with "ju" --- Cargo.toml | 2 +- README.md | 2 +- src/lib.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e46bcf1c..41a910a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bytesize" -description = "an utility for human-readable bytes representations" +description = "a utility for human-readable bytes representations" version = "1.0.0" authors = ["Hyunsik Choi "] diff --git a/README.md b/README.md index 9c3464d0..d8369e61 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Crates.io Version](https://img.shields.io/crates/v/bytesize.svg)](https://crates.io/crates/bytesize) -ByteSize is an utility for human-readable byte count representation. +ByteSize is a utility for human-readable byte count representation. [API Documentation](https://docs.rs/bytesize/) diff --git a/src/lib.rs b/src/lib.rs index 26ffbd6e..25b9d2f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ -//! ByteSize is an utility that easily makes bytes size representation -//! and helps its arithmetic operations. +//! ByteSize is a utility that easily makes bytes size representation and helps +//! its arithmetic operations. //! //! ## Example //! From d3be6c858370662bb8eee90e5d8e0750ccf6c92a Mon Sep 17 00:00:00 2001 From: Christian Krause Date: Wed, 2 Jan 2019 14:48:51 +0100 Subject: [PATCH 2/4] adds costomizable byte formatters - this clarifies the intend beyond of what the previously used si boolean can - users may specify their own formatters - adds a byte formatter that is compatible with `sort -h` fixes #14 --- Cargo.toml | 2 +- src/lib.rs | 172 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 124 insertions(+), 50 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 41a910a6..d9235c10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "bytesize" description = "a utility for human-readable bytes representations" -version = "1.0.0" +version = "1.1.0" authors = ["Hyunsik Choi "] homepage = "https://github.com/hyunsik/bytesize/" diff --git a/src/lib.rs b/src/lib.rs index 25b9d2f8..ac2ba54a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,65 @@ pub fn pib>(size: V) -> u64 { size.into() * PIB } +/// 32 * 1024 Byte = 32 KiB +pub struct IEC; + +/// 32 * 1000 Byte = 32 KB +pub struct SI; + +/// 32 * 1024 Byte = 32K +pub struct Sort; + +fn humanize(bytes: u64, si: bool, prefix: &str, suffix: &str) -> String { + let unit = if si { KB } else { KIB }; + let unit_base = if si { LN_KB } else { LN_KIB }; + let unit_prefix = if si { + UNITS_SI.as_bytes() + } else { + UNITS.as_bytes() + }; + + if bytes < unit { + format!("{}{}B", bytes, prefix) + } else { + let size = bytes as f64; + let exp = match (size.ln() / unit_base) as usize { + e if e == 0 => 1, + e => e, + }; + + format!( + "{:.1}{}{}{}", + (size / unit.pow(exp as u32) as f64), + prefix, + unit_prefix[exp - 1] as char, + suffix + ) + } +} + +pub trait ByteFormatter { + fn humanize(&self, bytes: u64) -> String; +} + +impl ByteFormatter for IEC { + fn humanize(&self, bytes: u64) -> String { + humanize(bytes, false, " ", "iB") + } +} + +impl ByteFormatter for SI { + fn humanize(&self, bytes: u64) -> String { + humanize(bytes, true, " ", "B") + } +} + +impl ByteFormatter for Sort { + fn humanize(&self, bytes: u64) -> String { + humanize(bytes, false, "", "") + } +} + /// Byte size representation #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -169,43 +228,47 @@ impl ByteSize { self.0 } + #[deprecated(since = "1.1.0", note = "use `bs.humanize(SI|IEC)`")] #[inline(always)] pub fn to_string_as(&self, si_unit: bool) -> String { - to_string(self.0, si_unit) + if si_unit { + self.humanize(SI) + } else { + self.humanize(IEC) + } + } + + /// Returns humanized String representation. + /// + /// ## Examples + /// + /// ``` + /// # extern crate bytesize; + /// # use bytesize::*; + /// assert_eq!("1.0 KiB", ByteSize::b(1024).humanize(IEC)); + /// assert_eq!("1.0 kB", ByteSize::b(1000).humanize(SI)); + /// ``` + #[inline(always)] + pub fn humanize(&self, fmt: F) -> String + where + F: ByteFormatter, + { + fmt.humanize(self.0) } } +#[deprecated(since = "1.1.0", note = "use `ByteSize::b(bytes).humanize(SI|IEC)`")] pub fn to_string(bytes: u64, si_prefix: bool) -> String { - let unit = if si_prefix { KIB } else { KB }; - let unit_base = if si_prefix { LN_KIB } else { LN_KB }; - let unit_prefix = if si_prefix { - UNITS_SI.as_bytes() + if si_prefix { + humanize(bytes, si_prefix, " ", "B") } else { - UNITS.as_bytes() - }; - let unit_suffix = if si_prefix { "iB" } else { "B" }; - - if bytes < unit { - format!("{} B", bytes) - } else { - let size = bytes as f64; - let exp = match (size.ln() / unit_base) as usize { - e if e == 0 => 1, - e => e, - }; - - format!( - "{:.1} {}{}", - (size / unit.pow(exp as u32) as f64), - unit_prefix[exp - 1] as char, - unit_suffix - ) + humanize(bytes, si_prefix, " ", "iB") } } impl Display for ByteSize { fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "{}", to_string(self.0, false)) + write!(f, "{}", self.humanize(SI)) } } @@ -310,47 +373,58 @@ mod tests { #[test] fn test_display() { assert_display("215 B", ByteSize::b(215)); - assert_display("1.0 KB", ByteSize::kb(1)); - assert_display("301.0 KB", ByteSize::kb(301)); + assert_display("1.0 kB", ByteSize::kb(1)); + assert_display("301.0 kB", ByteSize::kb(301)); assert_display("419.0 MB", ByteSize::mb(419)); assert_display("518.0 GB", ByteSize::gb(518)); assert_display("815.0 TB", ByteSize::tb(815)); assert_display("609.0 PB", ByteSize::pb(609)); } - fn assert_to_string(expected: &str, b: ByteSize, si: bool) { - assert_eq!(expected.to_string(), b.to_string_as(si)); + fn assert_humanize(expected: &str, b: ByteSize, fmt: F) + where + F: ByteFormatter, + { + assert_eq!(expected.to_string(), b.humanize(fmt)); } #[test] - fn test_to_string_as() { - assert_to_string("215 B", ByteSize::b(215), true); - assert_to_string("215 B", ByteSize::b(215), false); + fn test_humanize() { + assert_humanize("215 B", ByteSize::b(215), IEC); + assert_humanize("215 B", ByteSize::b(215), SI); - assert_to_string("1.0 kiB", ByteSize::kib(1), true); - assert_to_string("1.0 KB", ByteSize::kib(1), false); + assert_humanize("1.0 KiB", ByteSize::kib(1), IEC); + assert_humanize("1.0 kB", ByteSize::kib(1), SI); + assert_humanize("1.0K", ByteSize::kib(1), Sort); - assert_to_string("293.9 kiB", ByteSize::kb(301), true); - assert_to_string("301.0 KB", ByteSize::kb(301), false); + assert_humanize("293.9 KiB", ByteSize::kb(301), IEC); + assert_humanize("301.0 kB", ByteSize::kb(301), SI); + assert_humanize("293.9K", ByteSize::kb(301), Sort); - assert_to_string("1.0 MiB", ByteSize::mib(1), true); - assert_to_string("1048.6 KB", ByteSize::mib(1), false); + assert_humanize("1.0 MiB", ByteSize::mib(1), IEC); + assert_humanize("1048.6 kB", ByteSize::mib(1), SI); + assert_humanize("1.0M", ByteSize::mib(1), Sort); // a bug case: https://github.com/flang-project/bytesize/issues/8 - assert_to_string("1.9 GiB", ByteSize::mib(1907), true); - assert_to_string("2.0 GB", ByteSize::mib(1908), false); + assert_humanize("1.9 GiB", ByteSize::mib(1907), IEC); + assert_humanize("2.0 GB", ByteSize::mib(1908), SI); + assert_humanize("1.9G", ByteSize::mib(1907), Sort); - assert_to_string("399.6 MiB", ByteSize::mb(419), true); - assert_to_string("419.0 MB", ByteSize::mb(419), false); + assert_humanize("399.6 MiB", ByteSize::mb(419), IEC); + assert_humanize("419.0 MB", ByteSize::mb(419), SI); + assert_humanize("399.6M", ByteSize::mb(419), Sort); - assert_to_string("482.4 GiB", ByteSize::gb(518), true); - assert_to_string("518.0 GB", ByteSize::gb(518), false); + assert_humanize("482.4 GiB", ByteSize::gb(518), IEC); + assert_humanize("518.0 GB", ByteSize::gb(518), SI); + assert_humanize("482.4G", ByteSize::gb(518), Sort); - assert_to_string("741.2 TiB", ByteSize::tb(815), true); - assert_to_string("815.0 TB", ByteSize::tb(815), false); + assert_humanize("741.2 TiB", ByteSize::tb(815), IEC); + assert_humanize("815.0 TB", ByteSize::tb(815), SI); + assert_humanize("741.2T", ByteSize::tb(815), Sort); - assert_to_string("540.9 PiB", ByteSize::pb(609), true); - assert_to_string("609.0 PB", ByteSize::pb(609), false); + assert_humanize("540.9 PiB", ByteSize::pb(609), IEC); + assert_humanize("609.0 PB", ByteSize::pb(609), SI); + assert_humanize("540.9P", ByteSize::pb(609), Sort); } #[test] @@ -360,6 +434,6 @@ mod tests { #[test] fn test_to_string() { - assert_to_string("609.0 PB", ByteSize::pb(609), false); + assert_humanize("609.0 PB", ByteSize::pb(609), SI); } } From f16ba51056fcf370548c661f35fe523fa6e03d59 Mon Sep 17 00:00:00 2001 From: Christian Krause Date: Wed, 2 Jan 2019 14:52:24 +0100 Subject: [PATCH 3/4] activates ignored crate documentation tests --- src/lib.rs | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ac2ba54a..9df8bba8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,30 +1,34 @@ //! ByteSize is a utility that easily makes bytes size representation and helps //! its arithmetic operations. //! -//! ## Example +//! ## Human Readable Representation //! -//! ```ignore +//! ByteSize provides a human readable string conversion as follows: +//! +//! ``` //! extern crate bytesize; //! -//! use bytesize::ByteSize; +//! use bytesize::{ByteSize, IEC, SI}; //! -//! fn byte_arithmetic_operator() { -//! let x = ByteSize::mb(1); -//! let y = ByteSize::kb(100); +//! assert_eq!("482.4 GiB".to_string(), ByteSize::gb(518).humanize(IEC)); +//! assert_eq!("518.0 GB".to_string(), ByteSize::gb(518).humanize(SI)); +//! ``` //! -//! let plus = x + y; -//! print!("{} bytes", plus.as_u64()); +//! ## Arithmetic //! -//! let minus = ByteSize::tb(100) - ByteSize::gb(4); -//! print!("{} bytes", minus.as_u64()); -//! } //! ``` +//! extern crate bytesize; +//! +//! use bytesize::ByteSize; +//! +//! let x = ByteSize::mb(1); +//! let y = ByteSize::kb(100); //! -//! It also provides its human readable string as follows: +//! let sum = x + y; +//! assert_eq!(sum, ByteSize::kb(1100)); //! -//! ```ignore= -//! assert_eq!("482 GiB".to_string(), ByteSize::gb(518).to_string(true)); -//! assert_eq!("518 GB".to_string(), ByteSize::gb(518).to_string(false)); +//! let product = 10u32 * x; +//! assert_eq!(product, ByteSize::mb(10)); //! ``` #[cfg(feature = "serde")] From 123ccb34d41d990ad6449705ca00eafb5d06ce5f Mon Sep 17 00:00:00 2001 From: Christian Krause Date: Wed, 2 Jan 2019 14:56:15 +0100 Subject: [PATCH 4/4] updates and simplifies README --- README.md | 80 +++++++++++-------------------------------------------- 1 file changed, 16 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index d8369e61..b050b6cb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ## ByteSize + [![Build Status](https://travis-ci.org/hyunsik/bytesize.svg?branch=master)](https://travis-ci.org/hyunsik/bytesize) [![Crates.io Version](https://img.shields.io/crates/v/bytesize.svg)](https://crates.io/crates/bytesize) - ByteSize is a utility for human-readable byte count representation. [API Documentation](https://docs.rs/bytesize/) @@ -16,80 +16,32 @@ Add this to your Cargo.toml: bytesize = "1.0.0" ``` -and this to your crate root: -```rust -extern crate bytesize; -``` +## Examples -## Example ### Human readable representations (SI unit and Binary unit) + ```rust -#[allow(dead_code)] -fn assert_display(expected: &str, b: ByteSize) { - assert_eq!(expected, format!("{}", b)); -} - -#[test] - fn test_display() { - assert_display("215 B", ByteSize(215)); - assert_display("215 B", ByteSize::b(215)); - assert_display("1.0 KB", ByteSize::kb(1)); - assert_display("301.0 KB", ByteSize::kb(301)); - assert_display("419.0 MB", ByteSize::mb(419)); - assert_display("518.0 GB", ByteSize::gb(518)); - assert_display("815.0 TB", ByteSize::tb(815)); - assert_display("609.0 PB", ByteSize::pb(609)); - } - - fn assert_to_string(expected: &str, b: ByteSize, si: bool) { - assert_eq!(expected.to_string(), b.to_string_as(si)); - } - - #[test] - 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); - - assert_to_string("1.0 kiB", ByteSize::kib(1), true); - assert_to_string("1.0 KB", ByteSize::kib(1), false); - - assert_to_string("293.9 kiB", ByteSize::kb(301), true); - assert_to_string("301.0 KB", ByteSize::kb(301), false); - - assert_to_string("1.0 MiB", ByteSize::mib(1), true); - assert_to_string("1048.6 KB", ByteSize::mib(1), false); - - assert_to_string("399.6 MiB", ByteSize::mb(419), true); - assert_to_string("419.0 MB", ByteSize::mb(419), false); - - assert_to_string("482.4 GiB", ByteSize::gb(518), true); - assert_to_string("518.0 GB", ByteSize::gb(518), false); - - assert_to_string("741.2 TiB", ByteSize::tb(815), true); - assert_to_string("815.0 TB", ByteSize::tb(815), false); - - assert_to_string("540.9 PiB", ByteSize::pb(609), true); - assert_to_string("609.0 PB", ByteSize::pb(609), false); -} +extern crate bytesize; + +use bytesize::{ByteSize, IEC SI}; + +assert_eq!("482.4 GiB".to_string(), ByteSize::gb(518).humanize(IEC)); +assert_eq!("518.0 GB".to_string(), ByteSize::gb(518).humanize(SI)); ``` ### Arithmetic operations + ```rust extern crate bytesize; use bytesize::ByteSize; -fn byte_arithmetic_operator() { - let x = ByteSize::mb(1); - let y = ByteSize::kb(100); +let x = ByteSize::mb(1); +let y = ByteSize::kb(100); - let plus = x + y; - print!("{}", plus); +let sum = x + y; +assert_eq!(sum, ByteSize::kb(1100)); - let minus = ByteSize::tb(100) + ByteSize::gb(4); - print!("{}", minus); -} +let product = 10u32 * x; +assert_eq!(product, ByteSize::mb(10)); ```