minting 1.7.3 → 1.8.1
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 +31 -24
- data/Rakefile +15 -4
- data/doc/Mint/Currency.html +535 -18
- data/doc/Mint/Money.html +659 -185
- data/doc/Mint/RangeStepPatch.html +1 -1
- data/doc/Mint/Registry.html +19 -2
- data/doc/Mint/Rounding.html +495 -0
- data/doc/Mint/UnknownCurrency.html +1 -1
- data/doc/Mint.html +187 -399
- data/doc/Minting.html +2 -2
- data/doc/_index.html +8 -1
- data/doc/agents/api_review-2026-06-15.md +0 -13
- data/doc/agents/copilot-instructions.md +70 -0
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +19 -9
- data/doc/index.html +19 -9
- data/doc/method_list.html +130 -42
- data/doc/top-level-namespace.html +1 -1
- data/lib/minting/currency/currency.rb +41 -2
- data/lib/minting/mint/dsl/numeric.rb +4 -4
- data/lib/minting/mint/dsl/range.rb +1 -0
- data/lib/minting/mint/dsl/string.rb +1 -1
- data/lib/minting/mint/mint.rb +10 -37
- data/lib/minting/mint/parser/parser.rb +50 -15
- data/lib/minting/mint/parser/separators.rb +10 -8
- data/lib/minting/mint/registry/zeros.rb +3 -1
- data/lib/minting/mint/rounding.rb +51 -0
- data/lib/minting/mint.rb +1 -0
- data/lib/minting/money/allocation/allocation.rb +1 -2
- data/lib/minting/money/allocation/split.rb +1 -1
- data/lib/minting/money/arithmetics/methods.rb +2 -2
- data/lib/minting/money/arithmetics/operators.rb +6 -6
- data/lib/minting/money/clamp.rb +1 -1
- data/lib/minting/money/coercion.rb +1 -1
- data/lib/minting/money/comparable.rb +6 -0
- data/lib/minting/money/constructors.rb +60 -12
- data/lib/minting/money/money.rb +0 -6
- data/lib/minting/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: baca6fa666461ab6bc9f1e0ebed40d7ae0ac56af88993b5d243d25f1ad9bbad3
|
|
4
|
+
data.tar.gz: e54ad7a337df49a298e0e6236ec98d46a902ddd18b62538d395992609eca533b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eff34626e551613b9dc312caf42698951869333aaf62440551e44eb681a8b2407e0a36ed24b02ba6f6ef03afc68dd1c7b6ac86aa85d3fafb45155f3637b70a04
|
|
7
|
+
data.tar.gz: b1d2f0f9228ef185ce8b86d4474a1d53151960d7796619ba53ff19fe0db53a9ad990e3f77f924b59c90cd984d144fb62f2fba56059f9e40dfeb5893f790e84cd
|
data/README.md
CHANGED
|
@@ -21,29 +21,19 @@ total.to_s #=> "$21.59"
|
|
|
21
21
|
total.currency_code #=> "USD"
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
| | Minting |
|
|
27
|
-
|--------------------|-------------------------------------------|
|
|
28
|
-
| **Precision** | Rational-based, zero floating-point error |
|
|
29
|
-
| **Performance** | **2× faster** (10×+ formatting) |
|
|
30
|
-
| **Ruby support** | 3.3+ (including Ruby 4.0) |
|
|
31
|
-
| **Rails** | Dedicated companion gem |
|
|
32
|
-
| **Code quality** | 100% coverage, 93/100 RubyCritic |
|
|
33
|
-
|
|
34
|
-
### 🎯 Exact precision
|
|
24
|
+
### Exact precision
|
|
35
25
|
Amounts are stored as `Rational` and rounded to the currency subunit. No floating-point surprises, ever.
|
|
36
26
|
|
|
37
|
-
###
|
|
38
|
-
Minting is
|
|
27
|
+
### Blazing performance
|
|
28
|
+
Minting is faster than the Money gem for everyday operations and **over 10× faster for formatting**. See full benchmarks in the [Performance Guide](test/performance/README.md).
|
|
39
29
|
|
|
40
|
-
###
|
|
30
|
+
### Clean, modern API
|
|
41
31
|
Intuitive interface, descriptive error messages, and sensible defaults. Works the way you expect.
|
|
42
32
|
|
|
43
|
-
###
|
|
33
|
+
### Rails-ready
|
|
44
34
|
Use with the [minting-rails](https://github.com/gferraz/minting-rails) companion gem for drop-in ActiveRecord type casting, validators, and form helpers.
|
|
45
35
|
|
|
46
|
-
###
|
|
36
|
+
### Quality code
|
|
47
37
|
- **100% test coverage** — every line exercised
|
|
48
38
|
- **93/100 RubyCritic score** — clean, maintainable code
|
|
49
39
|
- **CI-tested on Ruby 3.3 and 4.0**
|
|
@@ -176,12 +166,12 @@ Notes:
|
|
|
176
166
|
|
|
177
167
|
```ruby
|
|
178
168
|
# By ISO code (direct hash lookup, string only)
|
|
179
|
-
Mint.
|
|
169
|
+
Mint::Currency.for_code('USD') #=> #<Currency code="USD" ...>
|
|
180
170
|
|
|
181
171
|
# By display symbol (highest-priority currency for ambiguous symbols)
|
|
182
|
-
Mint.
|
|
183
|
-
Mint.
|
|
184
|
-
Mint.
|
|
172
|
+
Mint::Currency.for_symbol('$') #=> #<Currency code="USD" ...>
|
|
173
|
+
Mint::Currency.for_symbol('R$') #=> #<Currency code="BRL" ...>
|
|
174
|
+
Mint::Currency.for_symbol('€') #=> #<Currency code="EUR" ...>
|
|
185
175
|
|
|
186
176
|
```
|
|
187
177
|
|
|
@@ -189,15 +179,25 @@ Mint.currency_for_symbol('€') #=> #<Currency code="EUR" ...>
|
|
|
189
179
|
|
|
190
180
|
**Exact amounts** — Amounts are stored as `Rational` and rounded to the currency subunit.
|
|
191
181
|
|
|
182
|
+
**Rounding modes** — Wrap operations in `Mint.with_rounding(mode)` to change how amounts are rounded to the subunit:
|
|
183
|
+
|
|
184
|
+
```ruby
|
|
185
|
+
Mint.with_rounding(:half_down) { Mint.money(1.005, 'USD') } #=> [USD 1.00]
|
|
186
|
+
Mint.with_rounding(:ceil) { Mint.money(1.001, 'USD') } #=> [USD 1.01]
|
|
187
|
+
Mint.with_rounding(:floor) { Mint.parse('1.009', 'USD') } #=> [USD 1.00]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Modes: `:half_up` (default), `:half_down`, `:floor`, `:ceil`, `:truncate`, `:down`. Applies to construction, parsing, `change`, `split`, and `allocate`. Restores the previous mode when the block exits, even on exception.
|
|
191
|
+
|
|
192
192
|
**Refinements** — `10.dollars` and similar helpers require `using Mint` in the current scope (see Usage above).
|
|
193
193
|
|
|
194
194
|
**Division** — `money / 5` returns new `Money`; `money / other_money` returns a numeric ratio, not money.
|
|
195
195
|
|
|
196
196
|
**Zero equality** — Any zero amount is considered equal across currencies and to numeric zero (`Mint.money(0, 'USD') == Mint.money(0, 'EUR')` is intentionally `true`). Non-zero amounts must match currency and value.
|
|
197
197
|
|
|
198
|
-
**Zero helper** — `
|
|
198
|
+
**Zero helper** — `Currency.zero('USD')` returns a frozen zero-Money, useful as a default value for discounts, totals, or counters.
|
|
199
199
|
|
|
200
|
-
**Registered currencies** — `
|
|
200
|
+
**Registered currencies** — `Currency.register(code:, subunit:, symbol:, priority:)` adds custom currencies. Only registered codes and symbols are recognized by the parser.
|
|
201
201
|
|
|
202
202
|
**Built-in currencies** — 150+ ISO-4217 world currencies ship in `lib/minting/data/currencies.yaml` and load when the registry is first accessed.
|
|
203
203
|
|
|
@@ -216,11 +216,18 @@ Or at runtime:
|
|
|
216
216
|
Minting.use_top_level_constants!
|
|
217
217
|
```
|
|
218
218
|
|
|
219
|
+
For Rails applications, you can enable the top-level constants in an initializer:
|
|
220
|
+
|
|
221
|
+
```ruby
|
|
222
|
+
# config/initializers/minting.rb
|
|
223
|
+
require "minting/dsl"
|
|
224
|
+
```
|
|
225
|
+
|
|
219
226
|
After opting in:
|
|
220
227
|
|
|
221
228
|
```ruby
|
|
222
|
-
price = Money.
|
|
223
|
-
tax = Money.
|
|
229
|
+
price = Money.from(10, "USD") # equivalent to Mint::Money.from
|
|
230
|
+
tax = Money.from(2.50, "USD")
|
|
224
231
|
cur = Currency.new(code: "EUR", symbol: "€", subunit: 2, priority: 0)
|
|
225
232
|
```
|
|
226
233
|
|
data/Rakefile
CHANGED
|
@@ -16,7 +16,7 @@ end
|
|
|
16
16
|
|
|
17
17
|
Rake::TestTask.new('bench:all') do |t|
|
|
18
18
|
t.libs = %w[lib test]
|
|
19
|
-
t.pattern = 'test/performance
|
|
19
|
+
t.pattern = 'test/performance/{core,memory,regression,competitive/money}/*_benchmark.rb'
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
Rake::TestTask.new('bench:core') do |t|
|
|
@@ -34,9 +34,20 @@ Rake::TestTask.new('bench:regression') do |t|
|
|
|
34
34
|
t.pattern = 'test/performance/regression/*_benchmark.rb'
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
desc 'Run competitive benchmarks (Money gem)'
|
|
38
|
+
task 'bench:competitive' do
|
|
39
|
+
sh 'bundle exec ruby -Ilib -Itest -e "Dir[File.join(__dir__, \"test/performance/competitive/money/**/*_benchmark.rb\")].each { |f| require f }"'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc 'Run competitive benchmarks (Shopify Money)'
|
|
43
|
+
task 'bench:competitive:shopify' do
|
|
44
|
+
sh 'BUNDLE_WITHOUT=money_bench bundle exec ruby -Ilib -Itest -e "Dir[File.join(__dir__, \"test/performance/competitive/shopify/**/*_benchmark.rb\")].each { |f| require f }"'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
desc 'Run all competitive benchmarks (both Money and Shopify)'
|
|
48
|
+
task 'bench:competitive:all' do
|
|
49
|
+
sh 'bundle exec ruby -Ilib -Itest -e "Dir[File.join(__dir__, \"test/performance/competitive/money/**/*_benchmark.rb\")].each { |f| require f }"'
|
|
50
|
+
sh 'BUNDLE_WITHOUT=money_bench bundle exec ruby -Ilib -Itest -e "Dir[File.join(__dir__, \"test/performance/competitive/shopify/**/*_benchmark.rb\")].each { |f| require f }"'
|
|
40
51
|
end
|
|
41
52
|
|
|
42
53
|
desc 'Run core benchmarks and update the baseline'
|