Skip to content

Commit 81d19ce

Browse files
robjtedeAndrew15-5
andauthored
fix inverted SI / IEC conditions (#69)
* fix: swap values of `LN_KIB` & `LN_KB` * fix: invert SI/IEC conditions - Conditions that check whether the SI or IEC units must be used were inverted, i.e., when `si_prefix == true` it would use `"iB"` instead of `"B"`. - KB & kiB were used instead of kB & KiB. - Switches (true/false) in tests are also fixed. * fix: format with IEC (binary) by default * docs: doc units_* statics * refactor: move statics to consts * refactor: introduce format enum * test: use to_string_format in tests * chore: expand debug impl * fix: increase precision of LN_ constants --------- Co-authored-by: Andrew Voynov <andrewvoynov.b@gmail.com>
1 parent d89895f commit 81d19ce

File tree

5 files changed

+81
-44
lines changed

5 files changed

+81
-44
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
## Unreleased
44

5-
- Use SI format by default with `Display`.
6-
- Use "KiB" for SI unit.
5+
- Use IEC (binary) format by default with `Display`.
6+
- Use "kB" for SI unit.
77
- Implement `Sub<ByteSize>` for `ByteSize`.
88
- Implement `Sub<impl Into<u64>>` for `ByteSize`.
99
- Implement `SubAssign<ByteSize>` for `ByteSize`.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
name = "bytesize"
33
description = "A utility for human-readable byte count representations"
44
version = "1.3.0"
5-
authors = ["Hyunsik Choi <hyunsik.choi@gmail.com>", "MrCroxx <mrcroxx@outlook.com>"]
5+
authors = [
6+
"Hyunsik Choi <hyunsik.choi@gmail.com>",
7+
"MrCroxx <mrcroxx@outlook.com>",
8+
"Rob Ede <robjtede@icloud.com>",
9+
]
610
keywords = ["byte", "byte-size", "utility", "human-readable", "format"]
711
categories = ["development-tools", "filesystem"]
812
repository = "https://github.com/bytesize-rs/bytesize"

src/lib.rs

Lines changed: 70 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
//! ```
2525
//! use bytesize::ByteSize;
2626
//!
27-
//! assert_eq!("482.4 GiB", ByteSize::gb(518).to_string_as(true));
28-
//! assert_eq!("518.0 GB", ByteSize::gb(518).to_string_as(false));
27+
//! assert_eq!("482.4 GiB", ByteSize::gb(518).to_string_as(false));
28+
//! assert_eq!("518.0 GB", ByteSize::gb(518).to_string_as(true));
2929
//! ```
3030
//!
3131
//! Arithmetic operations are supported.
@@ -71,10 +71,28 @@ pub const TIB: u64 = 1_099_511_627_776;
7171
/// bytes size for 1 pebibyte
7272
pub const PIB: u64 = 1_125_899_906_842_624;
7373

74-
static UNITS: &str = "KMGTPE";
75-
static UNITS_SI: &str = "KMGTPE";
76-
static LN_KB: f64 = 6.931471806; // ln 1024
77-
static LN_KIB: f64 = 6.907755279; // ln 1000
74+
/// IEC (binary) units.
75+
///
76+
/// See <https://en.wikipedia.org/wiki/Kilobyte>.
77+
const UNITS_IEC: &str = "KMGTPE";
78+
79+
/// SI (decimal) units.
80+
///
81+
/// See <https://en.wikipedia.org/wiki/Kilobyte>.
82+
const UNITS_SI: &str = "kMGTPE";
83+
84+
/// `ln(1024) ~= 6.931`
85+
const LN_KIB: f64 = 6.931_471_805_599_453;
86+
87+
/// `ln(1000) ~= 6.908`
88+
const LN_KB: f64 = 6.907_755_278_982_137;
89+
90+
#[derive(Debug, Clone, Default)]
91+
pub enum Format {
92+
#[default]
93+
IEC,
94+
SI,
95+
}
7896

7997
pub fn kb<V: Into<u64>>(size: V) -> u64 {
8098
size.into() * KB
@@ -188,15 +206,28 @@ impl ByteSize {
188206
}
189207
}
190208

191-
pub fn to_string(bytes: u64, si_prefix: bool) -> String {
192-
let unit = if si_prefix { KIB } else { KB };
193-
let unit_base = if si_prefix { LN_KIB } else { LN_KB };
194-
let unit_prefix = if si_prefix {
195-
UNITS_SI.as_bytes()
196-
} else {
197-
UNITS.as_bytes()
209+
pub fn to_string(bytes: u64, si_unit: bool) -> String {
210+
to_string_format(bytes, if si_unit { Format::SI } else { Format::IEC })
211+
}
212+
213+
pub fn to_string_format(bytes: u64, format: Format) -> String {
214+
let unit = match format {
215+
Format::IEC => KIB,
216+
Format::SI => KB,
217+
};
218+
let unit_base = match format {
219+
Format::IEC => LN_KIB,
220+
Format::SI => LN_KB,
221+
};
222+
223+
let unit_prefix = match format {
224+
Format::IEC => UNITS_IEC.as_bytes(),
225+
Format::SI => UNITS_SI.as_bytes(),
226+
};
227+
let unit_suffix = match format {
228+
Format::IEC => "iB",
229+
Format::SI => "B",
198230
};
199-
let unit_suffix = if si_prefix { "iB" } else { "B" };
200231

201232
if bytes < unit {
202233
format!("{} B", bytes)
@@ -218,13 +249,13 @@ pub fn to_string(bytes: u64, si_prefix: bool) -> String {
218249

219250
impl Display for ByteSize {
220251
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
221-
f.pad(&to_string(self.0, true))
252+
f.pad(&to_string_format(self.0, Format::IEC))
222253
}
223254
}
224255

225256
impl Debug for ByteSize {
226257
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
227-
write!(f, "{}", self)
258+
<Self as Display>::fmt(self, f)
228259
}
229260
}
230261

@@ -408,6 +439,7 @@ mod tests {
408439
assert!(ByteSize::b(0) < ByteSize::tib(1));
409440
}
410441

442+
#[track_caller]
411443
fn assert_display(expected: &str, b: ByteSize) {
412444
assert_eq!(expected, format!("{}", b));
413445
}
@@ -435,39 +467,39 @@ mod tests {
435467
assert_eq!("|--357 B---|", format!("|{:-^10}|", ByteSize(357)));
436468
}
437469

438-
fn assert_to_string(expected: &str, b: ByteSize, si: bool) {
439-
assert_eq!(expected.to_string(), b.to_string_as(si));
470+
#[track_caller]
471+
fn assert_to_string(expected: &str, b: ByteSize, format: Format) {
472+
assert_eq!(expected.to_string(), to_string_format(b.0, format));
440473
}
441474

442475
#[test]
443476
fn test_to_string_as() {
444-
assert_to_string("215 B", ByteSize::b(215), true);
445-
assert_to_string("215 B", ByteSize::b(215), false);
477+
assert_to_string("215 B", ByteSize::b(215), Format::IEC);
478+
assert_to_string("215 B", ByteSize::b(215), Format::SI);
446479

447-
assert_to_string("1.0 KiB", ByteSize::kib(1), true);
448-
assert_to_string("1.0 KB", ByteSize::kib(1), false);
480+
assert_to_string("1.0 KiB", ByteSize::kib(1), Format::IEC);
481+
assert_to_string("1.0 kB", ByteSize::kib(1), Format::SI);
449482

450-
assert_to_string("293.9 KiB", ByteSize::kb(301), true);
451-
assert_to_string("301.0 KB", ByteSize::kb(301), false);
483+
assert_to_string("293.9 KiB", ByteSize::kb(301), Format::IEC);
484+
assert_to_string("301.0 kB", ByteSize::kb(301), Format::SI);
452485

453-
assert_to_string("1.0 MiB", ByteSize::mib(1), true);
454-
assert_to_string("1048.6 KB", ByteSize::mib(1), false);
486+
assert_to_string("1.0 MiB", ByteSize::mib(1), Format::IEC);
487+
assert_to_string("1.0 MB", ByteSize::mib(1), Format::SI);
455488

456-
// a bug case: https://github.com/flang-project/bytesize/issues/8
457-
assert_to_string("1.9 GiB", ByteSize::mib(1907), true);
458-
assert_to_string("2.0 GB", ByteSize::mib(1908), false);
489+
assert_to_string("1.9 GiB", ByteSize::mib(1907), Format::IEC);
490+
assert_to_string("2.0 GB", ByteSize::mib(1908), Format::SI);
459491

460-
assert_to_string("399.6 MiB", ByteSize::mb(419), true);
461-
assert_to_string("419.0 MB", ByteSize::mb(419), false);
492+
assert_to_string("399.6 MiB", ByteSize::mb(419), Format::IEC);
493+
assert_to_string("419.0 MB", ByteSize::mb(419), Format::SI);
462494

463-
assert_to_string("482.4 GiB", ByteSize::gb(518), true);
464-
assert_to_string("518.0 GB", ByteSize::gb(518), false);
495+
assert_to_string("482.4 GiB", ByteSize::gb(518), Format::IEC);
496+
assert_to_string("518.0 GB", ByteSize::gb(518), Format::SI);
465497

466-
assert_to_string("741.2 TiB", ByteSize::tb(815), true);
467-
assert_to_string("815.0 TB", ByteSize::tb(815), false);
498+
assert_to_string("741.2 TiB", ByteSize::tb(815), Format::IEC);
499+
assert_to_string("815.0 TB", ByteSize::tb(815), Format::SI);
468500

469-
assert_to_string("540.9 PiB", ByteSize::pb(609), true);
470-
assert_to_string("609.0 PB", ByteSize::pb(609), false);
501+
assert_to_string("540.9 PiB", ByteSize::pb(609), Format::IEC);
502+
assert_to_string("609.0 PB", ByteSize::pb(609), Format::SI);
471503
}
472504

473505
#[test]
@@ -477,6 +509,6 @@ mod tests {
477509

478510
#[test]
479511
fn test_to_string() {
480-
assert_to_string("609.0 PB", ByteSize::pb(609), false);
512+
assert_to_string("609.0 PB", ByteSize::pb(609), Format::SI);
481513
}
482514
}

src/parse.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ impl std::str::FromStr for Unit {
181181

182182
#[cfg(test)]
183183
mod tests {
184+
use crate::to_string_format;
185+
184186
use super::*;
185187

186188
#[test]
@@ -234,8 +236,8 @@ mod tests {
234236

235237
assert_eq!(parse(&format!("{}", parse("128GB"))), 128 * Unit::GigaByte);
236238
assert_eq!(
237-
parse(&crate::to_string(parse("128.000 GiB"), true)),
238-
128 * Unit::GibiByte
239+
parse(&to_string_format(parse("128.000 GiB"), crate::Format::IEC)),
240+
128 * Unit::GibiByte,
239241
);
240242
}
241243
}

src/serde.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ mod tests {
9292
}
9393

9494
#[test]
95-
9695
fn test_serde_json() {
9796
let json = serde_json::to_string(&ByteSize::mib(1)).unwrap();
9897
assert_eq!(json, "\"1.0 MiB\"");

0 commit comments

Comments
 (0)