Class: SOF::Cycle::Parser

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/sof/cycle/parser.rb

Overview

This class is not intended to be referenced directly. This is an internal implementation of Cycle behavior.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(notation) ⇒ Parser

Returns a new instance of Parser.



59
60
61
62
63
# File 'lib/sof/cycle/parser.rb', line 59

def initialize(notation)
  @notation = notation&.upcase
  @match = @notation&.match(self.class.parts_regex)
  @time_span = nil
end

Instance Attribute Details

#matchObject (readonly)

Returns the value of attribute match.



65
66
67
# File 'lib/sof/cycle/parser.rb', line 65

def match
  @match
end

#notationObject (readonly)

Returns the value of attribute notation.



65
66
67
# File 'lib/sof/cycle/parser.rb', line 65

def notation
  @notation
end

Class Method Details

.dormant_capable_kindsObject

Deliberately a method, not a constant: handlers register as each file in sof/cycles loads, which happens after this file. A constant would capture the empty set and leave every dormant-capable kind unrecognized.



39
40
41
# File 'lib/sof/cycle/parser.rb', line 39

def self.dormant_capable_kinds
  Cycle.registry.cycle_classes.select(&:dormant_capable?).map(&:notation_id).compact.freeze
end

.for(notation_or_parser) ⇒ Object



43
44
45
46
47
# File 'lib/sof/cycle/parser.rb', line 43

def self.for(notation_or_parser)
  return notation_or_parser if notation_or_parser.is_a? self

  new(notation_or_parser)
end

.load(hash) ⇒ Object



49
50
51
52
53
54
55
56
57
# File 'lib/sof/cycle/parser.rb', line 49

def self.load(hash)
  hash.symbolize_keys!
  hash.reverse_merge!(volume: 1)
  keys = %i[volume kind period_count period_key]
  str = "V#{hash.values_at(*keys).join}"
  return new(str) unless hash[:from_date]

  new([str, "F#{hash[:from_date]}"].join)
end

.parts_regexObject

Built from the registry rather than written out, so an application that declares its own kind has its notation recognised too. Rebuilt whenever a class registers; cached in between, since parsing is hot.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/sof/cycle/parser.rb', line 20

def self.parts_regex
  pattern = [Cycle.registry.notation_pattern, Cycle::TimeSpan.period_registry.code_pattern]
  return @parts_regex if @parts_regex && @parts_regex_pattern == pattern

  @parts_regex_pattern = pattern
  kinds, periods = pattern
  @parts_regex = /
    ^(?<vol>V(?<volume>\d*))? # optional volume
    (?<set>(?<kind>#{kinds}) # kind
    (?<period_count>\d+) # period count
    (?<period_key>#{periods})?)? # period_key
    (?<from>F(?<from_date>\d{4}-\d{2}-\d{2}))?$ # optional from
  /ix
end

Instance Method Details

#==(other) ⇒ Object



86
# File 'lib/sof/cycle/parser.rb', line 86

def ==(other) = other.to_h == to_h

#activated_notation(date) ⇒ Object



80
81
82
83
84
# File 'lib/sof/cycle/parser.rb', line 80

def activated_notation(date)
  return notation unless dormant_capable?

  self.class.load(to_h.merge(from_date: date.to_date)).notation
end

#active?Boolean

Returns:

  • (Boolean)


100
# File 'lib/sof/cycle/parser.rb', line 100

def active? = !dormant?

#dormant?Boolean

Returns:

  • (Boolean)


102
# File 'lib/sof/cycle/parser.rb', line 102

def dormant? = dormant_capable? && from_date.nil?

#dormant_capable?Boolean

Returns:

  • (Boolean)


104
# File 'lib/sof/cycle/parser.rb', line 104

def dormant_capable? = kind.in?(dormant_capable_kinds)

#fromObject



122
# File 'lib/sof/cycle/parser.rb', line 122

def from = match[:from]

#from_dataObject



114
115
116
117
118
# File 'lib/sof/cycle/parser.rb', line 114

def from_data
  return {} unless from

  {from: from}
end

#from_dateObject



120
# File 'lib/sof/cycle/parser.rb', line 120

def from_date = match[:from_date]

#inspectObject Also known as: to_s



77
# File 'lib/sof/cycle/parser.rb', line 77

def inspect = notation

#kindObject



124
# File 'lib/sof/cycle/parser.rb', line 124

def kind = match[:kind]

#parses?(notation_id) ⇒ Boolean

Returns:

  • (Boolean)


98
# File 'lib/sof/cycle/parser.rb', line 98

def parses?(notation_id) = kind == notation_id

#period_countObject



106
# File 'lib/sof/cycle/parser.rb', line 106

def period_count = match[:period_count]

#period_keyObject



108
# File 'lib/sof/cycle/parser.rb', line 108

def period_key = match[:period_key]

#time_spanObject

Return a TimeSpan object for the period and period_count



71
72
73
# File 'lib/sof/cycle/parser.rb', line 71

def time_span
  @time_span ||= TimeSpan.for(period_count, period_key)
end

#to_hObject



88
89
90
91
92
93
94
95
96
# File 'lib/sof/cycle/parser.rb', line 88

def to_h
  {
    volume:,
    kind:,
    period_count:,
    period_key:,
    from_date:
  }
end

#valid?Boolean

Returns:

  • (Boolean)


75
# File 'lib/sof/cycle/parser.rb', line 75

def valid? = match.present?

#volObject



110
# File 'lib/sof/cycle/parser.rb', line 110

def vol = match[:vol] || "V1"

#volumeObject



112
# File 'lib/sof/cycle/parser.rb', line 112

def volume = (match[:volume] || 1).to_i