minting 1.1.2 → 1.2.0
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 +5 -0
- data/Rakefile +7 -2
- data/lib/minting/mint/currency.rb +6 -2
- data/lib/minting/mint/registry.rb +5 -2
- data/lib/minting/money/allocation.rb +2 -1
- data/lib/minting/money/arithmetics.rb +1 -1
- data/lib/minting/money/conversion.rb +5 -3
- data/lib/minting/money/money.rb +3 -4
- data/lib/minting/money/parse.rb +1 -1
- data/lib/minting/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b05d1cbbf6c714102f38f165effba77384e4fc5cebf691d4b9ab75082c22b992
|
|
4
|
+
data.tar.gz: 2d5bb5aeb6e527a2d4419bcca35d79c426709797975e9ec38217558d875ea9b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce7311d97cbe60c2f71ba5f65d1313704084eebae842e012c2cd857230055ef56007575e8f89887f8ae157c004d205e43370ada8d2fc2b5f3ea00b7c21c8017a
|
|
7
|
+
data.tar.gz: e4903099bb997667472ddc0c26ff07b3894bb9fa5122221c94045d84f2699e28d203646429e341a8119177a07212991f04d36c5806a12c8388766a3a8aebb6eb
|
data/README.md
CHANGED
|
@@ -91,6 +91,11 @@ price_in_euros.to_s(format: '%<symbol>2s%<amount>+10f') #=> " € +12.34"
|
|
|
91
91
|
|
|
92
92
|
price.to_json # => "{ "currency": "USD", "amount": "9.99" }"
|
|
93
93
|
|
|
94
|
+
# Hash conversion
|
|
95
|
+
|
|
96
|
+
price.to_hash #=> {currency: "USD", amount: "9.99"}
|
|
97
|
+
|
|
98
|
+
|
|
94
99
|
# Proportional allocation and split
|
|
95
100
|
|
|
96
101
|
ten.split(3) #=> [[USD 3.34], [USD 3.33], [USD 3.33]]
|
data/Rakefile
CHANGED
|
@@ -12,18 +12,23 @@ Rake::TestTask.new(:test) do |t|
|
|
|
12
12
|
t.ruby_opts << '-rtest_helper.rb'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
Rake::TestTask.new(
|
|
15
|
+
Rake::TestTask.new('bench') do |t|
|
|
16
16
|
t.libs = %w[lib test]
|
|
17
17
|
t.pattern = 'test/performance/*_benchmark.rb'
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
Rake::TestTask.new('bench:parse') do |t|
|
|
21
|
+
t.libs = %w[lib test]
|
|
22
|
+
t.pattern = 'test/performance/parse_benchmark.rb'
|
|
23
|
+
t.ruby_opts << '-r test_helper.rb'
|
|
24
|
+
end
|
|
25
|
+
|
|
20
26
|
Rake::TestTask.new('bench:edge') do |t|
|
|
21
27
|
t.libs = %w[lib test]
|
|
22
28
|
t.pattern = 'test/performance/algorithm_benchmark.rb'
|
|
23
29
|
t.ruby_opts << '-r test_helper.rb'
|
|
24
30
|
end
|
|
25
31
|
|
|
26
|
-
|
|
27
32
|
Rake::TestTask.new('bench:regression') do |t|
|
|
28
33
|
t.libs = %w[lib test]
|
|
29
34
|
t.pattern = 'test/performance/regression_benchmark.rb'
|
|
@@ -3,7 +3,10 @@ module Mint
|
|
|
3
3
|
#
|
|
4
4
|
# @see https://www.iso.org/iso-4217-currency-codes.html
|
|
5
5
|
class Currency
|
|
6
|
-
attr_reader :code, :subunit, :symbol,
|
|
6
|
+
attr_reader :code, :subunit, :symbol,
|
|
7
|
+
:country,
|
|
8
|
+
:fractional_multiplier, :minimum_amount,
|
|
9
|
+
:name, :priority
|
|
7
10
|
|
|
8
11
|
def inspect
|
|
9
12
|
"<Currency:(#{code} #{symbol} #{subunit})>"
|
|
@@ -18,7 +21,8 @@ module Mint
|
|
|
18
21
|
@priority = priority.to_i
|
|
19
22
|
@country = country
|
|
20
23
|
@name = name
|
|
21
|
-
@
|
|
24
|
+
@fractional_multiplier = 10**@subunit
|
|
25
|
+
@minimum_amount = 1r / fractional_multiplier
|
|
22
26
|
freeze
|
|
23
27
|
end
|
|
24
28
|
end
|
|
@@ -14,6 +14,9 @@ module Mint
|
|
|
14
14
|
raise ArgumentError, "Currency [#{currency_code}] not registered. Check Mint.currencies"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# Returns default zero, no currency money
|
|
18
|
+
def self.zero = @zero ||= Money.new(0, Mint.currency('XXX'))
|
|
19
|
+
|
|
17
20
|
# Finds a registered currency by its code, symbol,
|
|
18
21
|
# or retrieves it directly if already a Currency object.
|
|
19
22
|
#
|
|
@@ -34,11 +37,11 @@ module Mint
|
|
|
34
37
|
#
|
|
35
38
|
# @param code [String, Symbol] the unique currency code (e.g. 'USD', :EUR)
|
|
36
39
|
# @param subunit [Integer] the decimal subunit precision (defaults to 2)
|
|
37
|
-
# @param symbol [String] the display symbol (defaults to '
|
|
40
|
+
# @param symbol [String] the display symbol (defaults to '')
|
|
38
41
|
# @param priority [Integer] parser precedence priority (defaults to 0)
|
|
39
42
|
# @return [Currency] the registered or existing Currency instance
|
|
40
43
|
# @raise [ArgumentError] if the code layout is invalid or register throws an error
|
|
41
|
-
def self.register_currency(code:, subunit: 2, symbol: '
|
|
44
|
+
def self.register_currency(code:, subunit: 2, symbol: '', priority: 0)
|
|
42
45
|
code = code.to_s
|
|
43
46
|
currencies[code] || register_currency!(code:, subunit:, symbol:, priority:)
|
|
44
47
|
end
|
|
@@ -14,7 +14,8 @@ module Mint
|
|
|
14
14
|
raise ArgumentError, 'Need at least 1 proportion element' if proportions.empty?
|
|
15
15
|
raise ArgumentError, 'Proportions total must not be zero' if whole.zero?
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
subunit = currency.subunit
|
|
18
|
+
amounts = proportions.map { |rate| (amount * rate.to_r / whole).round(subunit) }
|
|
18
19
|
allocate_left_over!(amounts: amounts, left_over: amount - amounts.sum)
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -39,15 +39,17 @@ module Mint
|
|
|
39
39
|
amount.to_i
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
def to_hash
|
|
43
|
+
{ currency: currency_code, amount: Kernel.format("%0.#{currency.subunit}f", amount) }
|
|
44
|
+
end
|
|
45
|
+
|
|
42
46
|
# Serializes the money instance to a standard JSON object containing the amount and currency.
|
|
43
47
|
# Highly optimized to run without external dependencies.
|
|
44
48
|
#
|
|
45
49
|
# @return [String] the JSON serialized string representation
|
|
46
50
|
def to_json(*_args)
|
|
47
|
-
subunit = currency.subunit
|
|
48
51
|
Kernel.format(
|
|
49
|
-
%({"currency": "#{currency_code}", "amount": "%0.#{subunit}f"}),
|
|
50
|
-
amount
|
|
52
|
+
%({"currency": "#{currency_code}", "amount": "%0.#{currency.subunit}f"}), amount
|
|
51
53
|
)
|
|
52
54
|
end
|
|
53
55
|
|
data/lib/minting/money/money.rb
CHANGED
|
@@ -24,6 +24,8 @@ module Mint
|
|
|
24
24
|
# @return [String] the ISO currency code
|
|
25
25
|
def currency_code = currency.code
|
|
26
26
|
|
|
27
|
+
def fractional = (amount * currency.fractional_multiplier).to_i
|
|
28
|
+
|
|
27
29
|
# Generates a stable hash key for Money instances.
|
|
28
30
|
#
|
|
29
31
|
# @return [Integer] the calculated hash value
|
|
@@ -33,7 +35,7 @@ module Mint
|
|
|
33
35
|
# @param new_amount [Numeric] The new amount
|
|
34
36
|
# @return [Money] A new Money object or self
|
|
35
37
|
def mint(new_amount)
|
|
36
|
-
new_amount
|
|
38
|
+
new_amount == amount ? self : Money.new(new_amount, currency)
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
# Returns a standard developer-oriented string inspection of the Money object.
|
|
@@ -48,8 +50,5 @@ module Mint
|
|
|
48
50
|
# @param other [Object] the target object to compare
|
|
49
51
|
# @return [Boolean] true if currencies match, false otherwise
|
|
50
52
|
def same_currency?(other) = other.respond_to?(:currency) && other.currency == currency
|
|
51
|
-
|
|
52
|
-
# Returns default zero no currency money
|
|
53
|
-
def self.zero = @zero ||= new(0, Mint.currencies('XXX'))
|
|
54
53
|
end
|
|
55
54
|
end
|
data/lib/minting/money/parse.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Mint
|
|
|
32
32
|
# Extracts a numeric value from input that should only contain an amount.
|
|
33
33
|
def self.parse_amount(input)
|
|
34
34
|
# Remove any charater that is not a digit, comma or period
|
|
35
|
-
numeric = input.scan(/[\d
|
|
35
|
+
numeric = input.scan(/[\d.,-]/).join
|
|
36
36
|
numeric = normalize_separators(numeric)
|
|
37
37
|
Rational(numeric)
|
|
38
38
|
end
|
data/lib/minting/version.rb
CHANGED