Class: Timeliness::FormatSet

Inherits:
Object
  • Object
show all
Defined in:
lib/timeliness/format_set.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(formats) ⇒ FormatSet

Returns a new instance of FormatSet.



11
12
13
14
15
# File 'lib/timeliness/format_set.rb', line 11

def initialize(formats)
  @formats       = formats
  @formats_hash  = {}
  @match_indexes = {}
end

Instance Attribute Details

#formatsObject (readonly)

Returns the value of attribute formats.



5
6
7
# File 'lib/timeliness/format_set.rb', line 5

def formats
  @formats
end

#regexpObject (readonly)

Returns the value of attribute regexp.



5
6
7
# File 'lib/timeliness/format_set.rb', line 5

def regexp
  @regexp
end

Class Method Details

.compile(formats) ⇒ Object



7
8
9
# File 'lib/timeliness/format_set.rb', line 7

def self.compile(formats)
  new(formats).compile!
end

Instance Method Details

#compile!Object

Compiles the formats into one big regexp. Stores the index of where each format’s capture values begin in the matchdata.



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/timeliness/format_set.rb', line 19

def compile!
  regexp_string = +''
  @formats.inject(0) { |index, format_string|
    format = Format.new(format_string).compile!
    @formats_hash[format_string] = format
    @match_indexes[index] = format
    regexp_string.concat("(?>#{format.regexp_string})|")
    index + format.token_count
  }
  @regexp = %r[\A(?:#{regexp_string.chop})\z]
  self
end

#match(string, format_string = nil) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/timeliness/format_set.rb', line 32

def match(string, format_string=nil)
  format = single_format(format_string) if format_string
  match_regexp = format ? format.regexp : @regexp

  if (match_data = match_regexp.match(string))
    captures = match_data.captures # For a multi-format regexp there are lots of nils
    index = captures.index { |e| !e.nil? } # Find the start of captures for matched format
    values = captures[index, 8]
    format ||= @match_indexes[index]
    format.process(*values)
  end
end

#single_format(format_string) ⇒ Object



45
46
47
# File 'lib/timeliness/format_set.rb', line 45

def single_format(format_string)
  @formats_hash.fetch(format_string) { Format.new(format_string).compile! }
end