Module: Philiprehberger::HumanSize
- Defined in:
- lib/philiprehberger/human_size.rb,
lib/philiprehberger/human_size/version.rb
Defined Under Namespace
Classes: Error
Constant Summary collapse
- SI_UNITS =
%w[B KB MB GB TB PB EB].freeze
- BINARY_UNITS =
%w[B KiB MiB GiB TiB PiB EiB].freeze
- SI_BASE =
1000- BINARY_BASE =
1024- PARSE_PATTERN =
/\A\s*(-?\d+(?:\.\d+)?)\s*([a-z]+)\s*\z/i- UNIT_FACTORS =
{ 'B' => 1, 'KB' => 1000, 'MB' => 1000**2, 'GB' => 1000**3, 'TB' => 1000**4, 'PB' => 1000**5, 'EB' => 1000**6, 'KIB' => 1024, 'MIB' => 1024**2, 'GIB' => 1024**3, 'TIB' => 1024**4, 'PIB' => 1024**5, 'EIB' => 1024**6 }.freeze
- VERSION =
'0.7.0'
Class Method Summary collapse
-
.compare(a, b) ⇒ Integer
Spaceship comparison of two size values.
- .convert(bytes, unit:, precision: 2) ⇒ Object
-
.format(bytes, binary: false, precision: 2, compact: false) ⇒ String
Format a byte count as a human-readable string.
-
.format_compact(bytes, binary: false, precision: 2) ⇒ String
Format a byte count without the space between value and unit (e.g. ‘1.5MB`).
- .format_parts(bytes, binary: false, precision: 2) ⇒ Object
-
.format_rate(bytes, seconds, binary: false, precision: 2) ⇒ String
Format a throughput rate (bytes over a time window) as a human-readable string suffixed with ‘/s` (e.g. `1.5 MB/s`, `256 KiB/s`).
- .parse(string) ⇒ Object
- .valid?(string) ⇒ Boolean
Class Method Details
.compare(a, b) ⇒ Integer
Spaceship comparison of two size values
Each operand may be a size string (parsed via parse) or a ‘Numeric` byte count. Returns `-1`, `0`, or `1` exactly like Ruby’s ‘<=>` operator. Useful for sorting filenames by size, threshold checks, and table ordering.
105 106 107 |
# File 'lib/philiprehberger/human_size.rb', line 105 def compare(a, b) to_bytes(a) <=> to_bytes(b) end |
.convert(bytes, unit:, precision: 2) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/philiprehberger/human_size.rb', line 65 def convert(bytes, unit:, precision: 2) raise Error, 'bytes must be a Numeric' unless bytes.is_a?(Numeric) raise Error, 'unit must be a String' unless unit.is_a?(String) key = unit.upcase factor = UNIT_FACTORS[key] raise Error, "unknown unit: #{unit}" unless factor value = bytes.to_f / factor "#{sprintf("%.#{precision}f", value)} #{unit}" # rubocop:disable Style/FormatString end |
.format(bytes, binary: false, precision: 2, compact: false) ⇒ String
Format a byte count as a human-readable string.
41 42 43 44 45 46 |
# File 'lib/philiprehberger/human_size.rb', line 41 def format(bytes, binary: false, precision: 2, compact: false) parts = compute_parts(bytes, binary: binary, precision: precision) separator = compact ? '' : ' ' "#{format_value(parts[:value], parts[:unit_index], precision)}#{separator}#{parts[:unit]}" end |
.format_compact(bytes, binary: false, precision: 2) ⇒ String
Format a byte count without the space between value and unit (e.g. ‘1.5MB`). Equivalent to format with `compact: true`.
55 56 57 |
# File 'lib/philiprehberger/human_size.rb', line 55 def format_compact(bytes, binary: false, precision: 2) format(bytes, binary: binary, precision: precision, compact: true) end |
.format_parts(bytes, binary: false, precision: 2) ⇒ Object
59 60 61 62 63 |
# File 'lib/philiprehberger/human_size.rb', line 59 def format_parts(bytes, binary: false, precision: 2) parts = compute_parts(bytes, binary: binary, precision: precision) { value: parts[:value], unit: parts[:unit] } end |
.format_rate(bytes, seconds, binary: false, precision: 2) ⇒ String
Format a throughput rate (bytes over a time window) as a human-readable string suffixed with ‘/s` (e.g. `1.5 MB/s`, `256 KiB/s`).
86 87 88 89 90 91 92 |
# File 'lib/philiprehberger/human_size.rb', line 86 def format_rate(bytes, seconds, binary: false, precision: 2) raise Error, 'seconds must be a Numeric' unless seconds.is_a?(Numeric) raise Error, 'seconds must be positive' unless seconds.positive? per_second = bytes.to_f / seconds "#{format(per_second, binary: binary, precision: precision)}/s" end |
.parse(string) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/philiprehberger/human_size.rb', line 109 def parse(string) raise Error, 'input must be a String' unless string.is_a?(String) match = PARSE_PATTERN.match(string.strip) raise Error, "cannot parse: #{string.inspect}" unless match number = match[1].to_f unit = match[2].upcase factor = UNIT_FACTORS[unit] raise Error, "unknown unit: #{match[2]}" unless factor (number * factor).round end |
.valid?(string) ⇒ Boolean
124 125 126 127 128 129 130 131 |
# File 'lib/philiprehberger/human_size.rb', line 124 def valid?(string) return false unless string.is_a?(String) parse(string) true rescue Error false end |