Module: HumanNumber::LocaleSupport

Defined in:
lib/human_number/locale_support.rb

Overview

Shared locale support logic for both Number and Currency formatters.

This module provides centralized currency-to-locale mappings and locale resolution logic to ensure consistent precision and formatting rules across different formatters.

Constant Summary collapse

CURRENCY_NATIVE_LOCALES =

Mapping of currency codes to their primary native locales Used to determine appropriate precision and formatting rules

{
  "KRW" => [:ko],
  "JPY" => [:ja],
  "USD" => %i[en en-US],
  "EUR" => %i[de fr es it nl],
  "GBP" => %i[en-GB],
  "CAD" => %i[en-CA fr-CA],
  "CNY" => %i[zh zh-CN],
  "CHF" => %i[de fr it],
  "INR" => %i[hi en-IN],
  "RUB" => [:ru],
  "BRL" => %i[pt-BR],
  "MXN" => %i[es-MX],
  "AUD" => %i[en-AU],
  "NZD" => %i[en-NZ],
  "SEK" => [:sv],
  "NOK" => %i[no nb],
  "DKK" => [:da],
  "SGD" => %i[en-SG zh-SG],
  "HKD" => %i[zh-HK en-HK],
  "ZAR" => %i[en-ZA af],
  "TRY" => [:tr],
  "ARS" => %i[es-AR],
  "IDR" => [:id],
  "THB" => [:th],
  "MYR" => %i[ms en-MY],
  "PHP" => %i[en-PH tl],
  "VND" => [:vi],
}.freeze
SUPPORTED_NATIVE_CURRENCY_KEYS =

Keys supported for native currency formatting

%i[unit format].freeze

Class Method Summary collapse

Class Method Details

.currency_key(key) ⇒ String

Generates the I18n key for standard currency formatting.

Parameters:

  • key (Symbol) —

    Currency format key (:unit, :format, etc.)

Returns:

  • (String) —

    I18n key for standard currency formatting



90
91
92
# File 'lib/human_number/locale_support.rb', line 90

def currency_key(key)
  "number.currency.format.#{key}"
end

.currency_precision_locale(currency_code, _user_locale = nil) ⇒ Symbol

Returns the locale to use for currency precision rules in standard formatting. Always returns the currency's primary native locale to ensure consistent precision (e.g., USD always shows 2 decimals, JPY shows 0 decimals).

Parameters:

  • currency_code (String) —

    ISO 4217 currency code

  • user_locale (Symbol) —

    User's preferred locale (for context)

Returns:

  • (Symbol) —

    Locale for precision rules



54
55
56
# File 'lib/human_number/locale_support.rb', line 54

def currency_precision_locale(currency_code, _user_locale = nil)
  native_locales_for_currency(currency_code).first || :en
end

.lookup_currency_i18n_value(key, locale:, currency_code:) ⇒ String?

Looks up currency-related I18n values with native locale fallback.

Parameters:

  • key (Symbol) —

    Currency format key to look up

  • locale (Symbol) —

    Display locale

  • currency_code (String) —

    ISO 4217 currency code

Returns:

  • (String, nil) —

    I18n value or nil if not found



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/human_number/locale_support.rb', line 100

def lookup_currency_i18n_value(key, locale:, currency_code:)
  # Return nil for unknown currencies so formatters can fall back appropriately
  return nil if native_locales_for_currency(currency_code).empty?

  # For native locales and supported keys, try native formatting first
  # Additional validation: only currencies that actually have native symbols
  if SUPPORTED_NATIVE_CURRENCY_KEYS.include?(key)
    if native_locale?(currency_code, locale)
      native_key = native_currency_key(key)
      return I18n.t(native_key, locale:) if I18n.exists?(native_key, locale, fallback: false)
    else
      # For currency symbols (:unit) and format, use currency's native locale to ensure consistency
      # (e.g., USD always shows "$1,234.56" format, regardless of display locale)
      target_locale = native_locales_for_currency(currency_code).first || :en
      standard_key = currency_key(key)
      return I18n.t(standard_key, locale: target_locale, default: currency_code)
    end
  end

  # For other keys, use user's requested locale
  standard_key = currency_key(key)
  I18n.t(standard_key, locale:)
end

.native_currency_key(key) ⇒ String

Generates the I18n key for native currency formatting.

Parameters:

  • key (Symbol) —

    Currency format key (:unit, :format, etc.)

Returns:

  • (String) —

    I18n key for native currency formatting



82
83
84
# File 'lib/human_number/locale_support.rb', line 82

def native_currency_key(key)
  "number.currency.format.native_#{key}"
end

.native_locale?(currency_code, locale) ⇒ Boolean

Checks if a locale is considered native for a given currency.

Parameters:

  • currency_code (String) —

    ISO 4217 currency code

  • locale (Symbol) —

    Locale to check

Returns:

  • (Boolean) —

    Whether the locale is native for the currency



63
64
65
66
67
# File 'lib/human_number/locale_support.rb', line 63

def native_locale?(currency_code, locale)
  return false unless currency_code && locale

  native_locales_for_currency(currency_code).include?(locale.to_sym)
end

.native_locales_for_currency(currency_code) ⇒ Array<Symbol>

Returns all native locales for a given currency.

Parameters:

  • currency_code (String) —

    ISO 4217 currency code

Returns:

  • (Array<Symbol>) —

    Array of native locales for the currency



73
74
75
76
# File 'lib/human_number/locale_support.rb', line 73

def native_locales_for_currency(currency_code)
  currency_code = currency_code&.upcase
  CURRENCY_NATIVE_LOCALES[currency_code] || []
end