Skip to content

Port fixes and features from upstream bytesize#12

Merged
lthiery merged 1 commit into
mainfrom
upstream-steals
Jul 7, 2026
Merged

Port fixes and features from upstream bytesize#12
lthiery merged 1 commit into
mainfrom
upstream-steals

Conversation

@lthiery

@lthiery lthiery commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Bugs fixed (both reproduced in humanbyte before fixing)

f64 precision loss parsing integer byte counts: any string with a unit suffix went through f64, whose 53-bit mantissa rounds large counts — parse("9007199254740993B") returned ...992. Integer-valued numbers now take an exact u64 path. I diverged from upstream on overflow: they saturating_mul, we return ParseError (silently clamping "20000 PB" to u64::MAX seems worse than erroring).

Display/parse round-trip broken at the top of the range (found while comparing, not from upstream): our display prefix table always included E, so u64::MAX displays as "16.0 EiB" — but Unit had no exa arms, so humanbyte couldn't parse its own output. Round-trip now covered by a test over both formats at every unit boundary.

Features ported

  • Exabyte support: EB/EIB constants, Unit::ExaByte/ExbiByte, eb()/eib() constructors
  • iter::Sum for derived types (owned and by-ref): sizes.iter().sum::<ByteScale>()
  • Float accessors: as_kb(), as_mib(), etc.
  • Formatter precision: format!("{size:.2}") now means 2 decimals ("1.50 KiB"). Previously Formatter::pad interpreted precision as string truncation, so {:.2} produced "1." — arguably a third bug. Width/alignment/fill still work and the existing alignment tests pass unchanged.
  • Unit gains Debug/Clone/Copy/PartialEq/Eq and #[non_exhaustive]

Bug fixes (from bytesize-rs/bytesize):
- parse: use exact integer arithmetic when the number has no fractional
  part; f64's 53-bit mantissa silently rounded large byte counts
  ("9007199254740993B" parsed to ...992). Overflow now errors instead
  of wrapping (bytesize#171, adapted: checked_mul + ParseError instead
  of saturating)
- display/parse round-trip: the display prefix table already emitted
  "16.0 EiB" for u64::MAX but the parser had no exa arms, so humanbyte
  couldn't parse back its own output

Features:
- exabyte support: EB/EIB constants, Unit::ExaByte/ExbiByte, eb()/eib()
  constructors
- iter::Sum for derived types (owned and by-ref)
- as_kb()/as_mib()/... float accessors on derived types
- Display now honors formatter precision as decimals ({:.2} gives
  "1.50 KiB"); previously precision truncated the string ({:.2} gave
  "1."). Width/alignment/fill preserved
- Unit gains Debug/Clone/Copy/PartialEq/Eq and #[non_exhaustive]

Not ported: their ln()-based unit-selection fix (bytesize#175) - our
integer-log display is already exact at boundaries
@lthiery lthiery merged commit a38cf06 into main Jul 7, 2026
1 check passed
@lthiery lthiery deleted the upstream-steals branch July 7, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant