Class: SOF::Cycle::Parser
- Inherits:
-
Object
- Object
- SOF::Cycle::Parser
- 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
-
#match ⇒ Object
readonly
Returns the value of attribute match.
-
#notation ⇒ Object
readonly
Returns the value of attribute notation.
Class Method Summary collapse
-
.dormant_capable_kinds ⇒ Object
Deliberately a method, not a constant: handlers register as each file in sof/cycles loads, which happens after this file.
- .for(notation_or_parser) ⇒ Object
- .load(hash) ⇒ Object
-
.parts_regex ⇒ Object
Built from the registry rather than written out, so an application that declares its own kind has its notation recognised too.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #activated_notation(date) ⇒ Object
- #active? ⇒ Boolean
- #dormant? ⇒ Boolean
- #dormant_capable? ⇒ Boolean
- #from ⇒ Object
- #from_data ⇒ Object
- #from_date ⇒ Object
-
#initialize(notation) ⇒ Parser
constructor
A new instance of Parser.
- #inspect ⇒ Object (also: #to_s)
- #kind ⇒ Object
- #parses?(notation_id) ⇒ Boolean
- #period_count ⇒ Object
- #period_key ⇒ Object
-
#time_span ⇒ Object
Return a TimeSpan object for the period and period_count.
- #to_h ⇒ Object
- #valid? ⇒ Boolean
- #vol ⇒ Object
- #volume ⇒ Object
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
#match ⇒ Object (readonly)
Returns the value of attribute match.
65 66 67 |
# File 'lib/sof/cycle/parser.rb', line 65 def match @match end |
#notation ⇒ Object (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_kinds ⇒ Object
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_regex ⇒ Object
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
100 |
# File 'lib/sof/cycle/parser.rb', line 100 def active? = !dormant? |
#dormant? ⇒ Boolean
102 |
# File 'lib/sof/cycle/parser.rb', line 102 def dormant? = dormant_capable? && from_date.nil? |
#dormant_capable? ⇒ Boolean
104 |
# File 'lib/sof/cycle/parser.rb', line 104 def dormant_capable? = kind.in?(dormant_capable_kinds) |
#from ⇒ Object
122 |
# File 'lib/sof/cycle/parser.rb', line 122 def from = match[:from] |
#from_data ⇒ Object
114 115 116 117 118 |
# File 'lib/sof/cycle/parser.rb', line 114 def from_data return {} unless from {from: from} end |
#from_date ⇒ Object
120 |
# File 'lib/sof/cycle/parser.rb', line 120 def from_date = match[:from_date] |
#inspect ⇒ Object Also known as: to_s
77 |
# File 'lib/sof/cycle/parser.rb', line 77 def inspect = notation |
#kind ⇒ Object
124 |
# File 'lib/sof/cycle/parser.rb', line 124 def kind = match[:kind] |
#parses?(notation_id) ⇒ Boolean
98 |
# File 'lib/sof/cycle/parser.rb', line 98 def parses?(notation_id) = kind == notation_id |
#period_count ⇒ Object
106 |
# File 'lib/sof/cycle/parser.rb', line 106 def period_count = match[:period_count] |
#period_key ⇒ Object
108 |
# File 'lib/sof/cycle/parser.rb', line 108 def period_key = match[:period_key] |
#time_span ⇒ Object
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_h ⇒ Object
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
75 |
# File 'lib/sof/cycle/parser.rb', line 75 def valid? = match.present? |
#vol ⇒ Object
110 |
# File 'lib/sof/cycle/parser.rb', line 110 def vol = match[:vol] || "V1" |
#volume ⇒ Object
112 |
# File 'lib/sof/cycle/parser.rb', line 112 def volume = (match[:volume] || 1).to_i |