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 VND].freeze

Class Method Summary collapse

Class Method Details

.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)


49
50
51
# File 'lib/timeprice/supported.rb', line 49

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



61
62
63
# File 'lib/timeprice/supported.rb', line 61

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.



30
31
32
# File 'lib/timeprice/supported.rb', line 30

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)


55
56
57
# File 'lib/timeprice/supported.rb', line 55

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



67
68
69
# File 'lib/timeprice/supported.rb', line 67

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.



35
36
37
# File 'lib/timeprice/supported.rb', line 35

def currency_to_country
  country_to_currency.invert.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)


43
44
45
# File 'lib/timeprice/supported.rb', line 43

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