Class: Timeprice::Point
- Inherits:
-
Data
- Object
- Data
- Timeprice::Point
- Defined in:
- lib/timeprice/point.rb
Overview
A (currency, date) pair used as input to compare.
The library accepts either a Point or a 2-element array. Arrays may be ordered either way (‘[“USD”, “2010”]` or `[“2010”, “USD”]`) — the year and currency are detected by shape. This mirrors what the CLI already tolerates and removes the only “which slot is which?” footgun.
Instance Attribute Summary collapse
-
#currency ⇒ Object
readonly
Returns the value of attribute currency.
-
#date ⇒ Object
readonly
Returns the value of attribute date.
Class Method Summary collapse
-
.coerce(input) ⇒ Point
Coerce input into a Point.
- .malformed_pair_message(input) ⇒ Object
-
.parse(currency, date) ⇒ Object
Canonical constructor.
Instance Method Summary collapse
-
#fx_anchor_date ⇒ String
Resolve ‘date` to a full YYYY-MM-DD for FX lookup.
Instance Attribute Details
#currency ⇒ Object (readonly)
Returns the value of attribute currency
17 18 19 |
# File 'lib/timeprice/point.rb', line 17 def currency @currency end |
#date ⇒ Object (readonly)
Returns the value of attribute date
17 18 19 |
# File 'lib/timeprice/point.rb', line 17 def date @date end |
Class Method Details
.coerce(input) ⇒ Point
Coerce input into a Point. Accepts:
- {Point} (returned as-is)
- 2-element Array of [currency, date] in either order
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/timeprice/point.rb', line 31 def self.coerce(input) case input in Point input in [_, _] a, b = input.map(&:to_s) currency = [a, b].find { |s| s.match?(/\A[A-Za-z]{3}\z/) } date = [a, b].find { |s| s.match?(/\A\d{4}(-\d{2}(-\d{2})?)?\z/) } fail ArgumentError, (input) if currency.nil? || date.nil? new(currency: currency.upcase, date: date) else fail ArgumentError, "Expected Timeprice::Point or [currency, date] tuple, got #{input.inspect}" end end |
.malformed_pair_message(input) ⇒ Object
47 48 49 50 |
# File 'lib/timeprice/point.rb', line 47 def self.(input) "Could not detect currency + date in #{input.inspect} " \ "(expected a 3-letter currency and a YYYY[-MM[-DD]] date)" end |
.parse(currency, date) ⇒ Object
Canonical constructor. Accepts a stdlib-string or Timeprice::Date for the date argument; stores the canonical string form.
20 21 22 |
# File 'lib/timeprice/point.rb', line 20 def self.parse(currency, date) new(currency: currency.to_s.upcase, date: Timeprice::Date.coerce(date).to_s) end |
Instance Method Details
#fx_anchor_date ⇒ String
Resolve ‘date` to a full YYYY-MM-DD for FX lookup.
Coarser grains anchor to a representative day:
- "YYYY" → mid-year (YYYY-06-30)
- "YYYY-MM" → mid-month (YYYY-MM-15)
- "YYYY-MM-DD" → passes through
61 62 63 64 65 66 67 68 |
# File 'lib/timeprice/point.rb', line 61 def fx_anchor_date case date.to_s when /\A\d{4}\z/ then "#{date}-06-30" when /\A\d{4}-\d{2}\z/ then "#{date}-15" when /\A\d{4}-\d{2}-\d{2}\z/ then date.to_s else fail ArgumentError, "Invalid date for Point: #{date.inspect}" end end |