Class: Hegel::Generators::TimesGenerator

Inherits:
Hegel::Generator show all
Defined in:
lib/hegel/generators.rb,
sig/hegel.rbs

Overview

Hegel::Syntax::Methods#times. A time of day String, "HH:MM:SS.ffffff", in [min_value, max_value] (also "HH:MM:SS.ffffff" Strings), defaulting to the conventional full day (00:00:00.000000 through 23:59:59.999999 -- hegel-rust's own full_ranges::MIDNIGHT/LAST_MICROSECOND) when either bound is omitted.

Returns a String, not a Time: Ruby's stdlib has no type for a bare time of day (hour/minute/second/microsecond, with no date), and building one from Time would attach an arbitrary date component to a value that has none -- printing, comparing, or inspecting it would read as though that date meant something, when it is only ever a placeholder this generator invented to satisfy Time's own constructor. min_value/max_value share that same String representation, both for symmetry with the return value and because it is the only representation available on the input side either.

Opens no span, for the same reason DatesGenerator does not (one native call, HEGEL_LABEL_TIME sits below HEGEL_LABEL_REGEX in the same header list).

Constant Summary collapse

MIDNIGHT =

Returns:

  • (String)
"00:00:00.000000"
LAST_MICROSECOND =

Returns:

  • (String)
"23:59:59.999999"
FORMAT =

Matches exactly what #do_draw's own format("%02d:%02d:%02d.%06d", ...) produces, so parsing and formatting agree on the same shape.

Returns:

  • (Regexp)
/\A(\d{2}):(\d{2}):(\d{2})\.(\d{6})\z/

Instance Method Summary collapse

Methods inherited from Hegel::Generator

#filter, #map

Constructor Details

#initialize(min_value:, max_value:) ⇒ TimesGenerator

Returns a new instance of TimesGenerator.

Parameters:

  • min_value: (String, nil)
  • max_value: (String, nil)


665
666
667
668
669
# File 'lib/hegel/generators.rb', line 665

def initialize(min_value:, max_value:)
  super()
  @min_value = min_value
  @max_value = max_value
end

Instance Method Details

#do_draw(tc) ⇒ String

Parameters:

  • tc (Object)

Returns:

  • (String)

Raises:



671
672
673
674
675
676
677
678
# File 'lib/hegel/generators.rb', line 671

def do_draw(tc)
  min_parts = parse(@min_value || MIDNIGHT, "min_value")
  max_parts = parse(@max_value || LAST_MICROSECOND, "max_value")
  raise Hegel::Error, "times: max_value < min_value" if (max_parts <=> min_parts).negative?

  hour, minute, second, microsecond = tc.generate_time(min_parts, max_parts)
  format("%02d:%02d:%02d.%06d", hour, minute, second, microsecond)
end

#parse(value, name) ⇒ Array[Integer]

+value+'s hour/minute/second/microsecond as an Array of Integers, or raises if it is not a String matching FORMAT. This layer does not range-check the parsed fields (an hour of 99, say): measured against libhegel 0.32.5, hegel_generate_time already returns HEGEL_E_INVALID_ARG for an invalid time, translated by LibHegel.check! once #do_draw calls tc.generate_time, the same division of labor DomainsGenerator follows for its own out-of-range max_length.

Parameters:

  • value (Object)
  • name (String)

Returns:

  • (Array[Integer])

Raises:



690
691
692
693
694
695
# File 'lib/hegel/generators.rb', line 690

def parse(value, name)
  match = value.is_a?(String) && FORMAT.match(value)
  raise Hegel::Error, "times: #{name} must be \"HH:MM:SS.ffffff\", got #{value.inspect}" unless match

  match.captures.map(&:to_i)
end