Module: Lemans::Units

Defined in:
lib/lemans/units.rb

Overview

Durations and sizes as a human writes them ("30m", "2GB"), stored as seconds and megabytes. A bare number gets the obvious reading.

Constant Summary collapse

DURATION =
/\A(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)?\z/
DURATION_FACTORS =
{ "ms" => 0.001, "s" => 1, "m" => 60, "h" => 3600, "d" => 86_400 }.freeze
SIZE =
/\A(\d+(?:\.\d+)?)\s*(MB|GB|TB)?\z/i
SIZE_FACTORS =
{ "mb" => 1, "gb" => 1024, "tb" => 1024 * 1024 }.freeze

Class Method Summary collapse

Class Method Details

.megabytes(value, field:) ⇒ Object

Raises:



24
25
26
27
28
29
30
31
32
# File 'lib/lemans/units.rb', line 24

def megabytes(value, field:)
  return nil if value.nil?
  return finite_nonnegative(value, field, "a size").round if value.is_a?(Numeric)

  match = SIZE.match(value.to_s.strip)
  raise ConfigError, "#{field}: cannot read #{value.inspect} as a size (try 2GB, 512MB)" unless match

  (match[1].to_f * SIZE_FACTORS.fetch((match[2] || "mb").downcase)).round
end

.seconds(value, field:) ⇒ Object

Raises:



14
15
16
17
18
19
20
21
22
# File 'lib/lemans/units.rb', line 14

def seconds(value, field:)
  return nil if value.nil?
  return finite_nonnegative(value, field, "a duration") if value.is_a?(Numeric)

  match = DURATION.match(value.to_s.strip)
  raise ConfigError, "#{field}: cannot read #{value.inspect} as a duration (try 30m, 300s, 1h)" unless match

  match[1].to_f * DURATION_FACTORS.fetch(match[2] || "s")
end