Module: Timeprice::Supported

Defined in:
lib/timeprice/supported.rb

Overview

Supported country and currency codes, derived from ‘data/manifest.json`. Adding a country = drop a CPI file + regenerate the manifest. No code change required.

Everything that needs to know “which currency pairs with which CPI series” must read it from here.

Constant Summary collapse

ZERO_DECIMAL_CURRENCIES =

Currencies with no minor unit — formatted as whole numbers. This is ISO 4217 metadata, not bundled data, so it stays hardcoded.

%w[JPY KRW VND].freeze

Class Method Summary collapse

Class Method Details

.annual_only_currenciesArray<String>

Returns currencies served only annually (e.g. VND, RUB).

Returns:

  • (Array<String>)

    currencies served only annually (e.g. VND, RUB).



40
41
42
43
# File 'lib/timeprice/supported.rb', line 40

def annual_only_currencies
  manifest = DataLoader.load_manifest
  (manifest.dig("fx", "annual_only_currencies") || []).freeze
end

.countriesArray<String>

Returns frozen list of supported country codes.

Returns:

  • (Array<String>)

    frozen list of supported country codes.



18
19
20
# File 'lib/timeprice/supported.rb', line 18

def countries
  manifest_countries.map { |c| c["code"] }.freeze
end

.country?(country) ⇒ Boolean

Parameters:

  • country (String)

Returns:

  • (Boolean)


65
66
67
# File 'lib/timeprice/supported.rb', line 65

def country?(country)
  countries.include?(country.to_s.upcase)
end

.country_for_currency(currency) ⇒ String?

Returns country code, or nil if unsupported.

Parameters:

  • currency (String)

    ISO 4217 code (e.g. “USD”)

Returns:

  • (String, nil)

    country code, or nil if unsupported



77
78
79
# File 'lib/timeprice/supported.rb', line 77

def country_for_currency(currency)
  currency_to_country[currency.to_s.upcase]
end

.country_to_currencyHash{String=>String}

Returns country code → currency code.

Returns:

  • (Hash{String=>String})

    country code → currency code.



46
47
48
# File 'lib/timeprice/supported.rb', line 46

def country_to_currency
  manifest_countries.to_h { |c| [c["code"], c["currency"]] }.freeze
end

.currenciesArray<String>

Returns frozen list of supported currency codes (the FX base USD plus every currency the manifest declares).

Returns:

  • (Array<String>)

    frozen list of supported currency codes (the FX base USD plus every currency the manifest declares).



24
25
26
27
# File 'lib/timeprice/supported.rb', line 24

def currencies
  base = DataLoader.load_manifest.dig("fx", "base")
  ([base] + DataLoader.load_manifest.dig("fx", "currencies")).uniq.freeze
end

.currency?(currency) ⇒ Boolean

Parameters:

  • currency (String)

Returns:

  • (Boolean)


71
72
73
# File 'lib/timeprice/supported.rb', line 71

def currency?(currency)
  currencies.include?(currency.to_s.upcase)
end

.currency_for_country(country) ⇒ String?

Returns currency code, or nil if unsupported.

Parameters:

  • country (String)

    country code (e.g. “US”)

Returns:

  • (String, nil)

    currency code, or nil if unsupported



83
84
85
# File 'lib/timeprice/supported.rb', line 83

def currency_for_country(country)
  country_to_currency[country.to_s.upcase]
end

.currency_to_countryHash{String=>String}

Returns currency code → country code.

Returns:

  • (Hash{String=>String})

    currency code → country code.



51
52
53
# File 'lib/timeprice/supported.rb', line 51

def currency_to_country
  country_to_currency.invert.freeze
end

.daily_currenciesArray<String>

Returns currencies with daily FX observations.

Returns:

  • (Array<String>)

    currencies with daily FX observations.



30
31
32
33
34
35
36
37
# File 'lib/timeprice/supported.rb', line 30

def daily_currencies
  manifest = DataLoader.load_manifest
  list = manifest.dig("fx", "daily_currencies")
  return currencies if list.nil?

  base = manifest.dig("fx", "base")
  ([base] + list).uniq.freeze
end

.decimals_for(currency) ⇒ Integer

ISO 4217 minor-unit count for a currency. Falls back to 2 for unknown codes so callers can still render some value rather than crashing.

Parameters:

  • currency (String)

Returns:

  • (Integer)


59
60
61
# File 'lib/timeprice/supported.rb', line 59

def decimals_for(currency)
  ZERO_DECIMAL_CURRENCIES.include?(currency.to_s.upcase) ? 0 : 2
end