minting 1.7.2 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -1
- data/doc/Mint/Currency.html +285 -31
- data/doc/Mint/Money.html +79 -56
- data/doc/Mint/RangeStepPatch.html +1 -1
- data/doc/Mint/Registry.html +842 -0
- data/doc/Mint/UnknownCurrency.html +1 -1
- data/doc/Mint.html +345 -51
- data/doc/Minting.html +2 -2
- data/doc/_index.html +8 -8
- data/doc/agents/api_review-2026-06-15.md +342 -0
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +13 -2
- data/doc/index.html +13 -2
- data/doc/method_list.html +100 -36
- data/doc/top-level-namespace.html +1 -1
- data/lib/minting/currency/currency.rb +31 -0
- data/lib/minting/mint/locale_backend.rb +29 -0
- data/lib/minting/mint/mint.rb +23 -21
- data/lib/minting/mint/parser/parser.rb +3 -7
- data/lib/minting/mint/registry/registration.rb +33 -0
- data/lib/minting/mint/registry/registry.rb +38 -0
- data/lib/minting/mint/registry/symbols.rb +49 -0
- data/lib/minting/mint/registry/zeros.rb +18 -0
- data/lib/minting/mint.rb +13 -25
- data/lib/minting/money/constructors.rb +6 -11
- data/lib/minting/money/format/formatting.rb +16 -0
- data/lib/minting/money/format/to_s.rb +13 -4
- data/lib/minting/money/money.rb +12 -0
- data/lib/minting/version.rb +1 -1
- metadata +13 -8
- data/lib/minting/currency/currency_registry.rb +0 -67
- data/lib/minting/currency/world_currencies.rb +0 -16
- /data/doc/agents/{AGENTS.md → expired/AGENTS.md} +0 -0
- /data/doc/agents/{copilot-instructions.md → expired/copilot-instructions.md} +0 -0
- /data/doc/agents/{gemini_gem_evaluation.md → expired/gemini_gem_evaluation.md} +0 -0
- /data/doc/agents/{recommendations.md → expired/recommendations.md} +0 -0
- /data/doc/agents/{rubocop-issues.md → expired/rubocop-issues.md} +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mint
|
|
4
|
+
# :nodoc:
|
|
5
|
+
module Registry
|
|
6
|
+
# Returns the cached zero-Money for a currency, creating it if needed.
|
|
7
|
+
#
|
|
8
|
+
# @param currency [Currency] the currency object
|
|
9
|
+
# @return [Money] a frozen zero-Money
|
|
10
|
+
# @api private
|
|
11
|
+
def self.zero_for(currency)
|
|
12
|
+
MUTEX.synchronize do
|
|
13
|
+
@zeros ||= {}
|
|
14
|
+
@zeros[currency] ||= Mint::Money.send(:new, 0, currency)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/minting/mint.rb
CHANGED
|
@@ -1,27 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
require 'minting/money/allocation/allocation'
|
|
17
|
-
require 'minting/money/allocation/split'
|
|
18
|
-
require 'minting/money/arithmetics/methods'
|
|
19
|
-
require 'minting/money/arithmetics/operators'
|
|
20
|
-
require 'minting/money/clamp'
|
|
21
|
-
require 'minting/money/coercion'
|
|
22
|
-
require 'minting/money/comparable'
|
|
23
|
-
require 'minting/money/constructors'
|
|
24
|
-
require 'minting/money/conversion'
|
|
25
|
-
require 'minting/money/format/formatting'
|
|
26
|
-
require 'minting/money/format/to_s'
|
|
27
|
-
require 'minting/money/money'
|
|
3
|
+
require_relative 'currency/currency'
|
|
4
|
+
|
|
5
|
+
require_relative 'mint/dsl/numeric'
|
|
6
|
+
require_relative 'mint/dsl/range'
|
|
7
|
+
require_relative 'mint/dsl/string'
|
|
8
|
+
require_relative 'mint/dsl/top_level'
|
|
9
|
+
require_relative 'mint/locale_backend'
|
|
10
|
+
require_relative 'mint/mint'
|
|
11
|
+
require_relative 'mint/parser/parser'
|
|
12
|
+
require_relative 'mint/parser/separators'
|
|
13
|
+
require_relative 'mint/registry/registry'
|
|
14
|
+
|
|
15
|
+
require_relative 'money/money'
|
|
@@ -10,12 +10,10 @@ module Mint
|
|
|
10
10
|
def self.create(amount, currency)
|
|
11
11
|
raise ArgumentError, 'amount must be Numeric' unless amount.is_a?(Numeric)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
currency = Currency.resolve!(currency)
|
|
14
|
+
amount = currency.normalize_amount(amount)
|
|
15
15
|
|
|
16
|
-
amount
|
|
17
|
-
|
|
18
|
-
amount.zero? ? Mint.zero(checked_currency) : new(amount, checked_currency)
|
|
16
|
+
amount.zero? ? Mint.zero(currency) : new(amount, currency)
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
# Builds a Money from a fractional (smallest-unit) Integer amount.
|
|
@@ -39,12 +37,9 @@ module Mint
|
|
|
39
37
|
def self.from_fractional(fractional, currency)
|
|
40
38
|
raise ArgumentError, 'fractional must be an Integer' unless fractional.is_a?(Integer)
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
amount = Rational(fractional, checked_currency.fractional_multiplier)
|
|
46
|
-
|
|
47
|
-
amount.zero? ? Mint.zero(checked_currency) : new(amount, checked_currency)
|
|
40
|
+
currency = Currency.resolve!(currency)
|
|
41
|
+
amount = Rational(fractional, currency.fractional_multiplier)
|
|
42
|
+
amount.zero? ? Mint.zero(currency) : new(amount, currency)
|
|
48
43
|
end
|
|
49
44
|
|
|
50
45
|
# Returns a new Money object with the specified amount, or self if unchanged.
|
|
@@ -5,6 +5,22 @@ module Mint
|
|
|
5
5
|
class Money
|
|
6
6
|
private
|
|
7
7
|
|
|
8
|
+
# Resolves format/decimal/thousand from locale_backend when not explicitly given.
|
|
9
|
+
# @private
|
|
10
|
+
def resolve_locale_for(format, decimal, thousand)
|
|
11
|
+
locale = locale_backend
|
|
12
|
+
[format || locale[:format] || '%<symbol>s%<amount>f',
|
|
13
|
+
decimal || locale[:decimal] || '.',
|
|
14
|
+
thousand || locale[:thousand] || ',']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def locale_backend
|
|
18
|
+
bk = Mint.locale_backend
|
|
19
|
+
return {} unless bk.respond_to?(:call)
|
|
20
|
+
|
|
21
|
+
bk.call
|
|
22
|
+
end
|
|
23
|
+
|
|
8
24
|
# Selects the appropriate format template and value based on the amount's sign.
|
|
9
25
|
# @private
|
|
10
26
|
def select_format(format)
|
|
@@ -5,7 +5,7 @@ module Mint
|
|
|
5
5
|
class Money
|
|
6
6
|
# Formats money as a string with customizable format, thousand delimiter, and decimal
|
|
7
7
|
#
|
|
8
|
-
# @param format [String, Hash] Either a Format string with placeholders
|
|
8
|
+
# @param format [String, Hash, nil] Either a Format string with placeholders
|
|
9
9
|
# (%<symbol>s, %<amount>f, %<currency>s), or a Hash with per-sign keys
|
|
10
10
|
# (:positive, :negative, :zero) each holding a format string. A Hash
|
|
11
11
|
# is convenient for sign-aware formats such as accounting parentheses:
|
|
@@ -15,8 +15,12 @@ module Mint
|
|
|
15
15
|
# Missing keys fall back to the module default, so a Hash with only
|
|
16
16
|
# :negative will still format positives sensibly. The valid keys are
|
|
17
17
|
# :positive, :negative, :zero; anything else raises ArgumentError.
|
|
18
|
-
#
|
|
19
|
-
#
|
|
18
|
+
# When +nil+, falls back to +Mint.locale_backend+ if set, otherwise
|
|
19
|
+
# +"%<symbol>s%<amount>f"+.
|
|
20
|
+
# @param thousand [String, false, nil] Thousands delimiter (e.g., ',' for 1,000).
|
|
21
|
+
# When +nil+, falls back to +Mint.locale_backend+ if set, otherwise +","+.
|
|
22
|
+
# @param decimal [String, nil] Decimal separator (e.g., '.' or ',').
|
|
23
|
+
# When +nil+, falls back to +Mint.locale_backend+ if set, otherwise +"."+.
|
|
20
24
|
# @return [String] Formatted money string
|
|
21
25
|
#
|
|
22
26
|
# @raise [ArgumentError] if +format+ is not a String or Hash, the Hash
|
|
@@ -43,7 +47,12 @@ module Mint
|
|
|
43
47
|
# money.to_s(format: '%<amount>10.2f') #=> " 1234.56"
|
|
44
48
|
# money.to_s(format: '%<symbol>s%<amount>010.2f') #=> "$0001234.56"
|
|
45
49
|
#
|
|
46
|
-
|
|
50
|
+
# @example Locale-aware formatting (with Mint.locale_backend set)
|
|
51
|
+
# money.to_s # decimal and thousand come from locale_backend
|
|
52
|
+
#
|
|
53
|
+
def to_s(format: nil, decimal: nil, thousand: nil, width: nil)
|
|
54
|
+
format, decimal, thousand = resolve_locale_for(format, decimal, thousand)
|
|
55
|
+
|
|
47
56
|
case format
|
|
48
57
|
when {}, '' then raise ArgumentError, 'format must not be empty'
|
|
49
58
|
when Hash then validate_format_hash(format)
|
data/lib/minting/money/money.rb
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative 'allocation/allocation'
|
|
4
|
+
require_relative 'allocation/split'
|
|
5
|
+
require_relative 'arithmetics/methods'
|
|
6
|
+
require_relative 'arithmetics/operators'
|
|
7
|
+
require_relative 'clamp'
|
|
8
|
+
require_relative 'coercion'
|
|
9
|
+
require_relative 'comparable'
|
|
10
|
+
require_relative 'constructors'
|
|
11
|
+
require_relative 'conversion'
|
|
12
|
+
require_relative 'format/formatting'
|
|
13
|
+
require_relative 'format/to_s'
|
|
14
|
+
|
|
3
15
|
module Mint
|
|
4
16
|
# Money constructors
|
|
5
17
|
class Money
|
data/lib/minting/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: minting
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.7.
|
|
4
|
+
version: 1.7.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gilson Ferraz
|
|
@@ -41,14 +41,16 @@ files:
|
|
|
41
41
|
- doc/Mint/CurrencyRegistry.html
|
|
42
42
|
- doc/Mint/Money.html
|
|
43
43
|
- doc/Mint/RangeStepPatch.html
|
|
44
|
+
- doc/Mint/Registry.html
|
|
44
45
|
- doc/Mint/UnknownCurrency.html
|
|
45
46
|
- doc/Minting.html
|
|
46
47
|
- doc/_index.html
|
|
47
|
-
- doc/agents/
|
|
48
|
-
- doc/agents/
|
|
49
|
-
- doc/agents/
|
|
50
|
-
- doc/agents/
|
|
51
|
-
- doc/agents/
|
|
48
|
+
- doc/agents/api_review-2026-06-15.md
|
|
49
|
+
- doc/agents/expired/AGENTS.md
|
|
50
|
+
- doc/agents/expired/copilot-instructions.md
|
|
51
|
+
- doc/agents/expired/gemini_gem_evaluation.md
|
|
52
|
+
- doc/agents/expired/recommendations.md
|
|
53
|
+
- doc/agents/expired/rubocop-issues.md
|
|
52
54
|
- doc/class_list.html
|
|
53
55
|
- doc/css/common.css
|
|
54
56
|
- doc/css/full_list.css
|
|
@@ -64,8 +66,6 @@ files:
|
|
|
64
66
|
- doc/top-level-namespace.html
|
|
65
67
|
- lib/minting.rb
|
|
66
68
|
- lib/minting/currency/currency.rb
|
|
67
|
-
- lib/minting/currency/currency_registry.rb
|
|
68
|
-
- lib/minting/currency/world_currencies.rb
|
|
69
69
|
- lib/minting/data/world-currencies.yaml
|
|
70
70
|
- lib/minting/mint.rb
|
|
71
71
|
- lib/minting/mint/aliases.rb
|
|
@@ -73,9 +73,14 @@ files:
|
|
|
73
73
|
- lib/minting/mint/dsl/range.rb
|
|
74
74
|
- lib/minting/mint/dsl/string.rb
|
|
75
75
|
- lib/minting/mint/dsl/top_level.rb
|
|
76
|
+
- lib/minting/mint/locale_backend.rb
|
|
76
77
|
- lib/minting/mint/mint.rb
|
|
77
78
|
- lib/minting/mint/parser/parser.rb
|
|
78
79
|
- lib/minting/mint/parser/separators.rb
|
|
80
|
+
- lib/minting/mint/registry/registration.rb
|
|
81
|
+
- lib/minting/mint/registry/registry.rb
|
|
82
|
+
- lib/minting/mint/registry/symbols.rb
|
|
83
|
+
- lib/minting/mint/registry/zeros.rb
|
|
79
84
|
- lib/minting/money/allocation/allocation.rb
|
|
80
85
|
- lib/minting/money/allocation/split.rb
|
|
81
86
|
- lib/minting/money/arithmetics/methods.rb
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'yaml'
|
|
4
|
-
|
|
5
|
-
# Mint currency store (internal)
|
|
6
|
-
module Mint
|
|
7
|
-
# Internal currency registry
|
|
8
|
-
# Manages the registry cache and currency symbol lookups.
|
|
9
|
-
module CurrencyRegistry
|
|
10
|
-
extend self
|
|
11
|
-
|
|
12
|
-
# Returns the hash of all registered currencies.
|
|
13
|
-
#
|
|
14
|
-
# @return [Hash{String => Currency}] registered currencies mapped by code
|
|
15
|
-
# @api private
|
|
16
|
-
def currencies
|
|
17
|
-
@currencies ||= Mint.world_currencies.dup
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Registered symbols sorted for detection: longest match wins, then parser priority.
|
|
21
|
-
#
|
|
22
|
-
# @return [Array<Array<String, Currency>>] sorted symbol-to-currency mappings
|
|
23
|
-
# @api private
|
|
24
|
-
def currency_symbols
|
|
25
|
-
@currency_symbols ||= begin
|
|
26
|
-
currencies.values
|
|
27
|
-
.reject { |c| c.symbol.empty? }
|
|
28
|
-
.map { |currency| [currency.symbol, currency] }
|
|
29
|
-
.sort_by { |symbol, currency| [-symbol.length, -currency.priority] }
|
|
30
|
-
end.freeze
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Registers a new currency, raising a KeyError if already registered.
|
|
34
|
-
#
|
|
35
|
-
# @param code [String] the unique currency code
|
|
36
|
-
# @param subunit [Integer] the decimal subunit precision, defaults to 0
|
|
37
|
-
# @param symbol [String] the display symbol
|
|
38
|
-
# @param priority [Integer] parser precedence priority
|
|
39
|
-
# @return [Currency] the newly registered Currency instance
|
|
40
|
-
# @raise [ArgumentError] if the code contains invalid characters
|
|
41
|
-
# @raise [KeyError] if the currency code is already registered
|
|
42
|
-
def register(code:, subunit: 0, symbol: '', priority: 0)
|
|
43
|
-
raise ArgumentError, 'Currency code must be String' unless code.is_a? String
|
|
44
|
-
unless code.match?(/^[A-Z_]+$/)
|
|
45
|
-
raise ArgumentError,
|
|
46
|
-
"Currency code must have only letters or '_' ('USD',, 'MY_COIN')"
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
currencies = CurrencyRegistry.currencies
|
|
50
|
-
raise KeyError, "Currency: #{code} already registered" if currencies[code]
|
|
51
|
-
|
|
52
|
-
currency = currencies[code] = Currency.new(code:, subunit:, symbol:, priority:)
|
|
53
|
-
invalidate_symbols_cache
|
|
54
|
-
currency
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
private
|
|
58
|
-
|
|
59
|
-
# Clears and refreshes the currency symbol cache.
|
|
60
|
-
# Called when currencies are registered.
|
|
61
|
-
#
|
|
62
|
-
# @api private
|
|
63
|
-
def invalidate_symbols_cache
|
|
64
|
-
@currency_symbols = nil
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Mint list of world currencies
|
|
4
|
-
module Mint
|
|
5
|
-
# Loads ISO world currencies from YAML file into the registry.
|
|
6
|
-
#
|
|
7
|
-
# @return [Hash{String => Currency}] ISO-4217 world currencies mapped by code
|
|
8
|
-
# @api private
|
|
9
|
-
def self.world_currencies
|
|
10
|
-
@world_currencies ||= begin
|
|
11
|
-
path = File.join(File.expand_path('../data', __dir__), 'world-currencies.yaml')
|
|
12
|
-
|
|
13
|
-
YAML.load_file(path).to_h { |entry| [entry['code'], Currency.new(**entry.transform_keys(&:to_sym))] }
|
|
14
|
-
end.freeze
|
|
15
|
-
end
|
|
16
|
-
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|