minting 1.9.5 → 1.9.6
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 +19 -19
- data/lib/minting/mint/mint.rb +4 -1
- data/lib/minting/money/conversion.rb +1 -1
- data/lib/minting/money/format/formatting.rb +18 -11
- data/lib/minting/money/format/to_s.rb +22 -22
- 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: 51f0a76084db98e53f29af4f82f1284f749c9691727a7a84a7f8cc758d1a9f67
|
|
4
|
+
data.tar.gz: f24a130df454ee80f923aa42fd995e4b3eaf2f4f16d1a6f3a9e84548c08a4988
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42ed5e90ba4a936426344cfd1f8aad69755038704c53b67d8f714ced040661e2f37829aa44d2d67f12575596656b7d9bd5b80058995b57875aaa46b2cf6dd291
|
|
7
|
+
data.tar.gz: a6490a3356b949df6889e72ee3fc885a4e10af8d14e09591d7bd615ea468371c30b1695b73e996cb91526ab824a610e2667797eb24e94144ec46ddd22dc42395
|
data/README.md
CHANGED
|
@@ -80,43 +80,43 @@ price = Mint.money(9.99, 'USD')
|
|
|
80
80
|
loss = Mint.money(-1234.56, 'USD')
|
|
81
81
|
|
|
82
82
|
# Built-in named presets
|
|
83
|
-
loss.
|
|
84
|
-
Mint.money(1234.56, 'EUR').
|
|
85
|
-
price.
|
|
86
|
-
price.
|
|
83
|
+
loss.format(:accounting) #=> "($1,234.56)"
|
|
84
|
+
Mint.money(1234.56, 'EUR').format(:european) #=> "1.234,56 €"
|
|
85
|
+
price.format(:amount) #=> "9.99"
|
|
86
|
+
price.format(:currency) #=> "USD 9.99"
|
|
87
87
|
|
|
88
88
|
# Presets can be overridden with explicit kwargs
|
|
89
|
-
Mint.money(1234.56, 'EUR').
|
|
89
|
+
Mint.money(1234.56, 'EUR').format(:european, format: '%<amount>f %<currency>s')
|
|
90
90
|
#=> "1.234,56 EUR"
|
|
91
91
|
|
|
92
92
|
# Or use direct format strings
|
|
93
|
-
price.
|
|
94
|
-
price.
|
|
95
|
-
price.
|
|
96
|
-
price.
|
|
97
|
-
(-price).
|
|
93
|
+
price.format #=> "$9.99",
|
|
94
|
+
price.format(format: '%<amount>d') #=> "9",
|
|
95
|
+
price.format(format: '%<symbol>s%<amount>f') #=> "$9.99",
|
|
96
|
+
price.format(format: '%<symbol>s%<amount>+f') #=> "$+9.99",
|
|
97
|
+
(-price).format(format: '%<amount>f') #=> "-9.99",
|
|
98
98
|
|
|
99
99
|
# Format with padding
|
|
100
100
|
price_in_euros = Mint.money(12.34, 'EUR')
|
|
101
101
|
|
|
102
|
-
price.
|
|
103
|
-
price.
|
|
104
|
-
(-price).
|
|
102
|
+
price.format(format: '--%<amount>7d') #=> "-- 9"
|
|
103
|
+
price.format(format: ' %<amount>10f %<currency>s') #=> " 9.99 USD"
|
|
104
|
+
(-price).format(format: ' %<amount>10f') #=> " -9.99"
|
|
105
105
|
|
|
106
|
-
price_in_euros.
|
|
106
|
+
price_in_euros.format(format: '%<symbol>2s%<amount>+10f') #=> " € +12.34"
|
|
107
107
|
|
|
108
108
|
# Integral & fractional parts
|
|
109
|
-
price.
|
|
110
|
-
Mint.money(0.99, 'USD').
|
|
109
|
+
price.format(format: '%<integral>d %<fractional>d/100') #=> "9 99/100"
|
|
110
|
+
Mint.money(0.99, 'USD').format(format: '%<integral>d dollars and %<fractional>02d cents')
|
|
111
111
|
#=> "0 dollars and 99 cents"
|
|
112
112
|
|
|
113
113
|
# Per-sign Hash format (e.g. accounting parentheses for losses)
|
|
114
114
|
loss = Mint.money(-1234.56, 'USD')
|
|
115
|
-
loss.
|
|
116
|
-
Mint.money(0, 'BRL').
|
|
115
|
+
loss.format(format: { negative: '(%<symbol>s%<amount>f)' }) #=> "($1,234.56)"
|
|
116
|
+
Mint.money(0, 'BRL').format(format: { zero: '--' }) #=> "--"
|
|
117
117
|
# All three keys at once:
|
|
118
118
|
fmt = { positive: '%<symbol>s%<amount>f', negative: '(%<symbol>s%<amount>f)', zero: '--' }
|
|
119
|
-
Mint.money(1234.56, 'USD').
|
|
119
|
+
Mint.money(1234.56, 'USD').format(format: fmt) #=> "$1,234.56"
|
|
120
120
|
|
|
121
121
|
# Json serialization
|
|
122
122
|
|
data/lib/minting/mint/mint.rb
CHANGED
|
@@ -12,7 +12,10 @@ module Mint
|
|
|
12
12
|
# Creates a new {Money} instance with the given amount and currency code.
|
|
13
13
|
#
|
|
14
14
|
# @param amount [Numeric] the financial value
|
|
15
|
-
# @param currency_code [Currency,
|
|
15
|
+
# @param currency_code [String, Currency, Money, nil] Currency code, object,
|
|
16
|
+
# Money whose currency to reuse, or +nil+. Passed through
|
|
17
|
+
# {Mint::Currency.resolve!} so all accepted types resolve to a registered
|
|
18
|
+
# currency.
|
|
16
19
|
# @return [Money] the instantiated Money object
|
|
17
20
|
# @raise [ArgumentError] if the amount is not a Numeric
|
|
18
21
|
# @raise [Mint::UnknownCurrency] if the currency code is not registered.
|
|
@@ -26,7 +26,7 @@ module Mint
|
|
|
26
26
|
# @return [String] HTML5 `<data>` representation
|
|
27
27
|
def to_html(format = DEFAULT_FORMAT)
|
|
28
28
|
title = Kernel.format("#{currency_code} %0.#{currency.subunit}f", amount)
|
|
29
|
-
body =
|
|
29
|
+
body = format(format: format)
|
|
30
30
|
%(<data class='money' title='#{title}'>#{ERB::Util.html_escape(body)}</data>)
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -33,10 +33,10 @@ module Mint
|
|
|
33
33
|
# @private
|
|
34
34
|
def validate_separators!(decimal:, thousand:)
|
|
35
35
|
case decimal
|
|
36
|
-
when
|
|
37
|
-
when
|
|
38
|
-
when
|
|
39
|
-
|
|
36
|
+
when nil # :noop
|
|
37
|
+
when '' then raise ArgumentError, 'decimal must be a non-empty'
|
|
38
|
+
when thousand then raise ArgumentError, "decimal and thousand cannot be identical: #{decimal.inspect}"
|
|
39
|
+
when String # :noop
|
|
40
40
|
else raise ArgumentError, "decimal must be a String, false, or nil, got #{decimal.inspect}"
|
|
41
41
|
end
|
|
42
42
|
|
|
@@ -62,13 +62,7 @@ module Mint
|
|
|
62
62
|
subunit = currency.subunit
|
|
63
63
|
resolved_format, adjusted_amount = resolve_format(format)
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
# e.g. '%<amount>f' becomes '%<amount>.2f' for USD
|
|
67
|
-
resolved_format = resolved_format.gsub(/%<amount>(\s*\+?\d*)f/, "%<amount>\\1.#{subunit}f")
|
|
68
|
-
|
|
69
|
-
# Zero-subunit currencies (e.g. JPY) have no fractional part —
|
|
70
|
-
# strip %<fractional>d specifiers entirely since there's no valid integer for "nothing"
|
|
71
|
-
resolved_format.gsub!(/%<fractional>[^%]*?d/, '') if subunit.zero?
|
|
65
|
+
resolved_format = inject_subunit_precision(resolved_format, subunit)
|
|
72
66
|
|
|
73
67
|
result = Kernel.format(resolved_format, {
|
|
74
68
|
amount: adjusted_amount,
|
|
@@ -86,5 +80,18 @@ module Mint
|
|
|
86
80
|
# Apply thousands only to the integral portion, using the decimal as boundary
|
|
87
81
|
apply_thousand_separator(result, decimal:, thousand:)
|
|
88
82
|
end
|
|
83
|
+
|
|
84
|
+
# Injects the currency's subunit precision into %<amount>f specifiers
|
|
85
|
+
# (e.g. '%<amount>f' → '%<amount>.2f' for USD). For zero-subunit
|
|
86
|
+
# currencies (e.g. JPY), strips %<fractional>d specifiers.
|
|
87
|
+
# @private
|
|
88
|
+
def inject_subunit_precision(template, subunit)
|
|
89
|
+
cache ||= {}
|
|
90
|
+
cache[[template, subunit]] ||= begin
|
|
91
|
+
result = template.gsub(/%<amount>(\s*\+?\d*)f/, "%<amount>\\1.#{subunit}f")
|
|
92
|
+
result.gsub!(/%<fractional>[^%]*?d/, '') if subunit.zero?
|
|
93
|
+
result.freeze
|
|
94
|
+
end
|
|
95
|
+
end
|
|
89
96
|
end
|
|
90
97
|
end
|
|
@@ -22,7 +22,7 @@ module Mint
|
|
|
22
22
|
# holding a format string. A Hash is convenient for sign-aware formats
|
|
23
23
|
# such as accounting parentheses:
|
|
24
24
|
#
|
|
25
|
-
# money.
|
|
25
|
+
# money.format(format: { negative: '(%<symbol>s%<amount>f)' })
|
|
26
26
|
#
|
|
27
27
|
# Missing keys fall back to the module default, so a Hash with only
|
|
28
28
|
# :negative will still format positives sensibly. The valid keys are
|
|
@@ -41,42 +41,42 @@ module Mint
|
|
|
41
41
|
#
|
|
42
42
|
# @example Basic formatting
|
|
43
43
|
# money = Mint.money(1234.56, 'USD')
|
|
44
|
-
# money.
|
|
45
|
-
# money.
|
|
46
|
-
# money.
|
|
44
|
+
# money.format #=> "$1,234.56"
|
|
45
|
+
# money.format(thousand: '.', decimal: ',') #=> "$1.234,56"
|
|
46
|
+
# money.format(decimal: ',', thousand: '') #=> "$1234,56"
|
|
47
47
|
#
|
|
48
48
|
# @example Preset formats
|
|
49
49
|
# loss = Mint.money(-1234.56, 'USD')
|
|
50
|
-
# loss.
|
|
51
|
-
# money.
|
|
52
|
-
# money.
|
|
53
|
-
# money.
|
|
50
|
+
# loss.format(:accounting) #=> "($1,234.56)"
|
|
51
|
+
# money.format(:european) #=> "1.234,56 €"
|
|
52
|
+
# money.format(:amount) #=> "1234.56"
|
|
53
|
+
# money.format(:currency) #=> "USD 1234.56"
|
|
54
54
|
#
|
|
55
55
|
# @example Custom formats
|
|
56
|
-
# money.
|
|
57
|
-
# money.
|
|
58
|
-
# money.
|
|
59
|
-
# money.
|
|
56
|
+
# money.format(format: '%<amount>f') #=> "1234.56"
|
|
57
|
+
# money.format(format: '%<currency>s %<amount>f') #=> "USD 1234.56"
|
|
58
|
+
# money.format(format: '%<amount>f %<symbol>s') #=> "1234.56 $"
|
|
59
|
+
# money.format(format: '%<symbol>s%<amount>+f') #=> "$+1234.56"
|
|
60
60
|
#
|
|
61
61
|
# @example Integral & fractional parts
|
|
62
|
-
# money.
|
|
62
|
+
# money.format(format: '%<integral>d.%<fractional>02d') #=> "1234.56"
|
|
63
63
|
# price = Mint.money(0.99, 'USD')
|
|
64
|
-
# price.
|
|
64
|
+
# price.format(format: '%<integral>d dollars and %<fractional>02d cents')
|
|
65
65
|
# #=> "0 dollars and 99 cents"
|
|
66
66
|
#
|
|
67
67
|
# @example Per-sign Hash format (accounting parentheses)
|
|
68
68
|
# loss = Mint.money(-1234.56, 'USD')
|
|
69
|
-
# loss.
|
|
70
|
-
# Mint.money(0, 'BRL').
|
|
69
|
+
# loss.format(format: { negative: '(%<symbol>s%<amount>f)' }) #=> "($1,234.56)"
|
|
70
|
+
# Mint.money(0, 'BRL').format(format: { zero: '--' }) #=> "--"
|
|
71
71
|
#
|
|
72
72
|
# @example Padding and alignment
|
|
73
|
-
# money.
|
|
74
|
-
# money.
|
|
73
|
+
# money.format(format: '%<amount>10.2f') #=> " 1234.56"
|
|
74
|
+
# money.format(format: '%<symbol>s%<amount>010.2f') #=> "$0001234.56"
|
|
75
75
|
#
|
|
76
76
|
# @example Locale-aware formatting (with Mint.locale_backend set)
|
|
77
|
-
# money.
|
|
77
|
+
# money.format # decimal and thousand come from locale_backend
|
|
78
78
|
#
|
|
79
|
-
def
|
|
79
|
+
def format(preset = nil, format: nil, decimal: nil, thousand: nil, width: nil)
|
|
80
80
|
if preset
|
|
81
81
|
config = PRESETS.fetch(preset) { raise ArgumentError, "Unknown format preset: #{preset.inspect}" }
|
|
82
82
|
format ||= config[:format]
|
|
@@ -101,8 +101,8 @@ module Mint
|
|
|
101
101
|
width ? formatted.rjust(width) : formatted
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
-
def to_s =
|
|
104
|
+
def to_s = format
|
|
105
105
|
|
|
106
|
-
alias to_fs
|
|
106
|
+
alias to_fs :format
|
|
107
107
|
end
|
|
108
108
|
end
|
data/lib/minting/version.rb
CHANGED