Class: Mint::Money::Formatter Private

Inherits:
Object
  • Object
show all
Extended by:
FormatterValidator
Defined in:
lib/minting/money/format/formatter.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Compiles and caches formatter lambdas for a fixed combination of format template, currency, and separator configuration.

Use Formatter.for to obtain a cached instance; avoid new directly unless you want an uncached formatter (typically only useful for testing).

Constant Summary collapse

CACHE_LIMIT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Keep enough compiled configurations for typical application presets and locales without retaining every caller-provided template indefinitely.

256
SIGNS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

{ -1 => '-', 0 => '', 1 => '+' }.freeze
SUBUNIT_PLACEHOLDER =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

"\uE000"
THOUSAND_RE =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Matches a digit followed by groups of exactly 3 digits that terminate at a non-digit or end-of-string. Used to insert thousand separators. e.g. "1234567" → "1" matches before "234" + "567" at string end.

/(\d)(?=(?:\d{3})+(?:[^\d]|$))/

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FormatterValidator

validate_format!, validate_separators!

Constructor Details

#initialize(format, decimal, thousand) ⇒ Formatter

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Formatter.



54
55
56
57
# File 'lib/minting/money/format/formatter.rb', line 54

def initialize(format, decimal, thousand)
  @decimal = decimal
  compile(format:, thousand:)
end

Class Attribute Details

.cache ⇒ Object (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



27
28
29
# File 'lib/minting/money/format/formatter.rb', line 27

def cache
  @cache
end

Class Method Details

.for(format, decimal, thousand) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a cached Mint::Money::Formatter for the given configuration. The cache is thread-safe and bounded by CACHE_LIMIT; once full, new configurations are compiled without being retained.

Parameters:

  • format (Hash{Symbol => String}) —

    per-sign templates

  • decimal (String) —

    decimal separator

  • thousand (String, false) —

    thousands delimiter (+false+ disables)



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/minting/money/format/formatter.rb', line 36

def self.for(format, decimal, thousand)
  key = [format, decimal, thousand]
  formatter = cache[key]
  return formatter if formatter

  CACHE_MUTEX.synchronize do
    formatter = cache[key]
    return formatter if formatter

    validate_format!(format)
    validate_separators!(decimal:, thousand:)

    formatter = new(format, decimal, thousand)
    @cache = cache.merge(key => formatter).freeze unless cache.size >= CACHE_LIMIT
    formatter
  end
end

Instance Method Details

#format(money) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/minting/money/format/formatter.rb', line 66

def format(money)
  amount = money.amount
  currency = money.currency

  templates = @has_placeholder ? @templates_by_subunit[currency.subunit] : @templates

  cmp = amount <=> 0
  template = templates[cmp] || templates[1]
  sign = SIGNS[cmp]

  magnitude = amount.abs
  display_amount = @has_negative_template ? magnitude : amount
  integral = display_amount.to_i

  result = Kernel.format(template,
                         currency: currency.code,
                         dsymbol: @needs_dsymbol && currency.dsymbol,
                         symbol: currency.symbol,
                         amount: display_amount,
                         magnitude:,
                         sign:,
                         integral: integral,
                         fractional: @needs_fractional ? money.fractional.abs : 0)
  apply_separators(result, integral)
end