minting 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +92 -0
- data/Rakefile +21 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/minting/currency.rb +2 -0
- data/lib/minting/mint/currency.rb +26 -0
- data/lib/minting/mint/refinements.rb +30 -0
- data/lib/minting/mint/registry.rb +57 -0
- data/lib/minting/mint.rb +3 -0
- data/lib/minting/money/allocation.rb +39 -0
- data/lib/minting/money/arithmetics.rb +50 -0
- data/lib/minting/money/coercion.rb +53 -0
- data/lib/minting/money/comparable.rb +53 -0
- data/lib/minting/money/conversion.rb +48 -0
- data/lib/minting/money/money.rb +39 -0
- data/lib/minting/money.rb +6 -0
- data/lib/minting/version.rb +3 -0
- data/lib/minting.rb +3 -0
- data/minting.gemspec +36 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c15130af9a863ae0ed77f63bd1fe5c9bf4c89e2f64bf116be16e5ace6407ede7
|
4
|
+
data.tar.gz: 749015ea7226c1ea4eafaa71d25461a812b29c0ec11541d686894aa55675bfe7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 797bd7de317d1038b3b5bf154cea1f0386dd7901bc598822820a51b680f600d0fce15219f8533f5da342092378639b6c663fe979b79ce7ac07578c1c13b9e59b
|
7
|
+
data.tar.gz: 0fc814e5e15fc40915baef2cef206c55a773072b67587b9e32373898bdb806194b78d63cf85e804c16939aabed753d7ad2b82e7db2948f749fa017ede7ca1172
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Minting
|
2
|
+
|
3
|
+
Yet another Ruby library for dealing with money and currency.
|
4
|
+
|
5
|
+
Work in progress, please wait release 1.0.0
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'minting', git: 'https://github.com/gferraz/minting.git'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself with:
|
20
|
+
|
21
|
+
$ git clone https://github.com/gferraz/minting.git
|
22
|
+
$ cd minting && gem build minting.gemspec
|
23
|
+
$ gem install minting-0.2.0.gem
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
require 'minting'
|
29
|
+
|
30
|
+
# 10.00 USD
|
31
|
+
ten_dollars = Mint.money(10, 'USD') #=> [USD 10.00]
|
32
|
+
ten_dollars.to_i #=> 10
|
33
|
+
ten_dollars.currency_code #=> "USD"
|
34
|
+
|
35
|
+
# Comparisons
|
36
|
+
ten_dollars = Mint.money(10, 'USD')
|
37
|
+
|
38
|
+
ten_dollars == Mint.money(10, 'USD') #=> true
|
39
|
+
ten_dollars == Mint.money(11, 'USD') #=> false
|
40
|
+
ten_dollars == Mint.money(10, 'EUR') #=> false
|
41
|
+
|
42
|
+
ten_dollars.eql? Mint.money(10, 'USD') #=> true
|
43
|
+
ten_dollars.hash == Mint.money(10, 'USD').hash #=> true
|
44
|
+
|
45
|
+
# Format (uses Kernel.format internally)
|
46
|
+
price = Mint.money(9.99, 'USD')
|
47
|
+
|
48
|
+
price.to_s #=> "$9.99",
|
49
|
+
price.to_s(format: '%<amount>d') #=> "9",
|
50
|
+
price.to_s(format: '%<symbol>s%<amount>f') #=> "$9.99",
|
51
|
+
price.to_s(format: '%<symbol>s%<amount>+f') #=> "$+9.99",
|
52
|
+
(-price).to_s(format: '%<amount>f') #=> "-9.99",
|
53
|
+
|
54
|
+
# Format with padding
|
55
|
+
price_in_euros = euro.money(12.34, 'EUR')
|
56
|
+
|
57
|
+
price.to_s(format: '--%<amount>7d') #=> "-- 9"
|
58
|
+
price.to_s(format: ' %<amount>10f %<currency>s') #=> " 9.99 USD"
|
59
|
+
(-price).to_s(format: ' %<amount>10f') #=> " -9.99"
|
60
|
+
|
61
|
+
price_in_euros.to_s(format: '%<symbol>2s%<amount>+10f') #=> " € +12.34"
|
62
|
+
|
63
|
+
# Json serialization
|
64
|
+
|
65
|
+
price.to_json # "{"currency": "USD", "amount": "9.99"}
|
66
|
+
|
67
|
+
# Allocation and split
|
68
|
+
|
69
|
+
ten_dollars.split(3) #=> [[USD 3.34], [USD 3.33], [USD 3.33]]
|
70
|
+
ten_dollars.split(7) #=> [[USD 1.42], [USD 1.43], [USD 1.43], [USD 1.43], [USD 1.43], [USD 1.43], [USD 1.43]]
|
71
|
+
|
72
|
+
ten_dollars.allocate([1, 2, 3]) #=> [[USD 1.67], [USD 3.33], [USD 5.00]]
|
73
|
+
|
74
|
+
# Numeric refinements
|
75
|
+
uning Mint
|
76
|
+
|
77
|
+
1.dollar == Mint.money(1, 'USD') #=> true
|
78
|
+
3.euros == Mint.money(2, 'EUR') #=> true
|
79
|
+
4.mint('USD') == 4.dollars #=> true
|
80
|
+
4.to_money('USD') == 4.dollars #=> true
|
81
|
+
```
|
82
|
+
|
83
|
+
## Release 1.0 Plan
|
84
|
+
|
85
|
+
- Rails
|
86
|
+
- Localization: I18n
|
87
|
+
- Arithmetics: div, mod
|
88
|
+
- Mint.parse
|
89
|
+
|
90
|
+
## Contributing
|
91
|
+
|
92
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gferraz/minting.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rubocop/rake_task'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
CLOBBER.include %w[tmp]
|
6
|
+
|
7
|
+
Rake::TestTask.new(:test) do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
t.libs << 'lib'
|
10
|
+
t.test_files = FileList['test/**/*_test.rb']
|
11
|
+
t.ruby_opts << '-rtest_helper.rb'
|
12
|
+
end
|
13
|
+
|
14
|
+
Rake::TestTask.new(:bench) do |t|
|
15
|
+
t.libs = %w[lib test]
|
16
|
+
t.pattern = 'test/**/*_benchmark.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
RuboCop::RakeTask.new(:cop)
|
20
|
+
|
21
|
+
task default: :test
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'minting'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# Represents a specific currency unit, identified by ISO 4217 alphabetic ocde
|
5
|
+
#
|
6
|
+
# @see https://www.iso.org/iso-4217-currency-codes.html
|
7
|
+
class Currency
|
8
|
+
attr_reader :code, :subunit, :symbol
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"<Currency:(#{code} #{symbol} #{subunit})>"
|
12
|
+
end
|
13
|
+
|
14
|
+
def minimum_amount
|
15
|
+
@minimum_amount ||= 10r**-subunit
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def initialize(code, subunit:, symbol:)
|
21
|
+
@code = code
|
22
|
+
@subunit = subunit
|
23
|
+
@symbol = symbol
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Mint is a library to operate with monetary values
|
2
|
+
module Mint
|
3
|
+
refine Numeric do
|
4
|
+
def reais
|
5
|
+
Mint.money(self, 'BRL')
|
6
|
+
end
|
7
|
+
|
8
|
+
def dollars
|
9
|
+
Mint.money(self, 'USD')
|
10
|
+
end
|
11
|
+
|
12
|
+
def euros
|
13
|
+
Mint.money(self, 'EUR')
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_money(currency)
|
17
|
+
Mint.money(self, currency)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias_method :dollar, :dollars
|
21
|
+
alias_method :euro, :euros
|
22
|
+
alias_method :mint, :to_money
|
23
|
+
end
|
24
|
+
|
25
|
+
refine String do
|
26
|
+
def to_money(currency)
|
27
|
+
Mint.money(to_r, currency)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# :nodoc
|
4
|
+
module Mint
|
5
|
+
def self.money(amount, currency_code)
|
6
|
+
Money.new(amount, currency(currency_code))
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.currency(currency)
|
10
|
+
case currency
|
11
|
+
when Currency
|
12
|
+
currency
|
13
|
+
when Symbol
|
14
|
+
currencies[currency.to_s]
|
15
|
+
else
|
16
|
+
currencies[currency]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.register_currency(code, subunit: 2, symbol: '$')
|
21
|
+
code = code.to_s
|
22
|
+
currencies[code] || register_currency!(code, subunit: subunit, symbol: symbol)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.register_currency!(code, subunit:, symbol: '')
|
26
|
+
code = code.to_s
|
27
|
+
unless code.match?(/^[A-Z_]+$/)
|
28
|
+
raise ArgumentError,
|
29
|
+
"Currency code must be String or Symbol ('USD', :EUR)"
|
30
|
+
end
|
31
|
+
if currencies[code]
|
32
|
+
raise KeyError,
|
33
|
+
"Currency: #{code} already registered"
|
34
|
+
end
|
35
|
+
|
36
|
+
currencies[code] =
|
37
|
+
Currency.new(code, subunit: subunit.to_i, symbol: symbol.to_s).freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.currencies
|
41
|
+
@currencies ||= {
|
42
|
+
'AUD' => Currency.new('AUD', subunit: 2, symbol: '$'),
|
43
|
+
'BRL' => Currency.new('BRL', subunit: 2, symbol: 'R$'),
|
44
|
+
'CAD' => Currency.new('CAD', subunit: 2, symbol: 'R$'),
|
45
|
+
'CHF' => Currency.new('CHF', subunit: 2, symbol: 'Fr'),
|
46
|
+
'CNY' => Currency.new('CNY', subunit: 2, symbol: '¥'),
|
47
|
+
'EUR' => Currency.new('EUR', subunit: 2, symbol: '€'),
|
48
|
+
'GBP' => Currency.new('GBP', subunit: 2, symbol: '£'),
|
49
|
+
'JPY' => Currency.new('JPY', subunit: 0, symbol: '¥'),
|
50
|
+
'MXN' => Currency.new('MXN', subunit: 2, symbol: '$'),
|
51
|
+
'NZD' => Currency.new('NZD', subunit: 2, symbol: '$'),
|
52
|
+
'PEN' => Currency.new('PEN', subunit: 2, symbol: 'S/.'),
|
53
|
+
'SEK' => Currency.new('SEK', subunit: 2, symbol: 'kr'),
|
54
|
+
'USD' => Currency.new('USD', subunit: 2, symbol: '$')
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
data/lib/minting/mint.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# :nodoc
|
5
|
+
# split and allocation methods
|
6
|
+
class Money
|
7
|
+
def allocate(proportions)
|
8
|
+
raise ArgumentError, 'Need at least 1 proportion element' if proportions.empty?
|
9
|
+
|
10
|
+
whole = proportions.sum.to_r
|
11
|
+
allocation = proportions.map { |rate| mint(amount * rate.to_r / whole) }
|
12
|
+
left_over = self - allocation.sum
|
13
|
+
allocate_left_over(allocation, left_over)
|
14
|
+
end
|
15
|
+
|
16
|
+
def split(quantity)
|
17
|
+
unless quantity.positive? && quantity.integer?
|
18
|
+
raise ArgumentError,
|
19
|
+
'quantitity must be an integer > 0'
|
20
|
+
end
|
21
|
+
|
22
|
+
fraction = self / quantity
|
23
|
+
allocation = Array.new(quantity, fraction)
|
24
|
+
left_over = self - (fraction * quantity)
|
25
|
+
allocate_left_over(allocation, left_over)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def allocate_left_over(allocation, left_over)
|
31
|
+
minimum = currency.minimum_amount
|
32
|
+
minimum = mint(left_over.positive? ? minimum : -minimum)
|
33
|
+
|
34
|
+
slots = (left_over / minimum).to_i - 1
|
35
|
+
(0..slots).each { |slot| allocation[slot] += minimum }
|
36
|
+
allocation
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# :nodoc
|
5
|
+
# Arithmetic funcions for money ojects
|
6
|
+
class Money
|
7
|
+
def abs
|
8
|
+
mint(amount.abs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def negative?
|
12
|
+
amount.negative?
|
13
|
+
end
|
14
|
+
|
15
|
+
def positive?
|
16
|
+
amount.positive?
|
17
|
+
end
|
18
|
+
|
19
|
+
def +(addend)
|
20
|
+
return mint(amount + addend.amount) if same_currency?(addend)
|
21
|
+
return self unless addend.is_a?(Money) || addend.nonzero?
|
22
|
+
|
23
|
+
raise TypeError, "#{addend} can't be added to #{self}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def -(subtrahend)
|
27
|
+
return self if subtrahend.zero?
|
28
|
+
return mint(amount - subtrahend.amount) if same_currency?(subtrahend)
|
29
|
+
|
30
|
+
raise TypeError, "#{subtrahend} can't be subtracted from #{self}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def -@
|
34
|
+
mint(-amount)
|
35
|
+
end
|
36
|
+
|
37
|
+
def *(multiplicand)
|
38
|
+
return mint(amount * multiplicand.to_r) if multiplicand.is_a?(Numeric)
|
39
|
+
|
40
|
+
raise TypeError, "#{self} can't be multiplied by #{multiplicand}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def /(divisor)
|
44
|
+
return mint(amount / divisor) if divisor.is_a?(Numeric)
|
45
|
+
return amount / divisor.amount if same_currency? divisor
|
46
|
+
|
47
|
+
raise TypeError, "#{self} can't be divided by #{divisor}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# :nodoc
|
5
|
+
# Coercion logic
|
6
|
+
class Money
|
7
|
+
def coerce(other)
|
8
|
+
[CoercedNumber.new(other), self]
|
9
|
+
end
|
10
|
+
|
11
|
+
# :nodoc
|
12
|
+
# Coerced Number contains the arithmetic logic for numeric compatible ops.
|
13
|
+
class CoercedNumber
|
14
|
+
include Comparable
|
15
|
+
|
16
|
+
def initialize(value)
|
17
|
+
@value = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def +(other)
|
21
|
+
return other if @value.zero?
|
22
|
+
|
23
|
+
raise_coercion_error(:+, other)
|
24
|
+
end
|
25
|
+
|
26
|
+
def -(other)
|
27
|
+
return -other if @value.zero?
|
28
|
+
|
29
|
+
raise_coercion_error(:-, other)
|
30
|
+
end
|
31
|
+
|
32
|
+
def *(other)
|
33
|
+
other.mint(@value * other.amount)
|
34
|
+
end
|
35
|
+
|
36
|
+
def /(other)
|
37
|
+
raise_coercion_error(:/, other)
|
38
|
+
end
|
39
|
+
|
40
|
+
def <=>(other)
|
41
|
+
return nil if @value.nil? || other.nil?
|
42
|
+
return @value <=> other.amount if @value.zero? || other.zero?
|
43
|
+
|
44
|
+
raise_coercion_error(:<=>, other)
|
45
|
+
end
|
46
|
+
|
47
|
+
def raise_coercion_error(operation, operand)
|
48
|
+
raise TypeError,
|
49
|
+
"#{self} #{operation} #{operand} : incompatible operands"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# :nodoc
|
5
|
+
# Comparision methods
|
6
|
+
class Money
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
# @return true if both are zero, or both have same amount and same currency
|
10
|
+
def ==(other)
|
11
|
+
return true if other.is_a?(Numeric) && zero? && other.zero?
|
12
|
+
return false unless other.is_a?(Mint::Money)
|
13
|
+
return false if nonzero? && currency != other.currency
|
14
|
+
|
15
|
+
amount == other.amount
|
16
|
+
end
|
17
|
+
|
18
|
+
# @example
|
19
|
+
# two_usd == Mint.money(2r, Currency['USD']) #=> [$ 2.00]
|
20
|
+
# two_usd > 0 #=> true
|
21
|
+
# two_usd > Mint.money(1r, Currency['USD']) #=> true
|
22
|
+
# two_usd > 1
|
23
|
+
# => TypeError: [$ 2.00] can't be compared to 1
|
24
|
+
# two_usd > Mint.money(2, Currency['BRL'])
|
25
|
+
# => TypeError: [$ 2.00] can't be compared to [R$ 2.00]
|
26
|
+
#
|
27
|
+
def <=>(other)
|
28
|
+
case other
|
29
|
+
when Numeric
|
30
|
+
return amount <=> other if other.zero?
|
31
|
+
when Mint::Money
|
32
|
+
return amount <=> other.amount if currency == other.currency
|
33
|
+
end
|
34
|
+
raise TypeError, "#{inspect} can't be compared to #{other.inspect}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def eql?(other)
|
38
|
+
self == other
|
39
|
+
end
|
40
|
+
|
41
|
+
def hash
|
42
|
+
@hash ||= zero? ? 0.hash : [amount, currency].hash
|
43
|
+
end
|
44
|
+
|
45
|
+
def nonzero?
|
46
|
+
amount.nonzero?
|
47
|
+
end
|
48
|
+
|
49
|
+
def zero?
|
50
|
+
amount.zero?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# Conversion logic
|
5
|
+
class Money
|
6
|
+
def to_d
|
7
|
+
amount.to_d 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_f
|
11
|
+
amount.to_f
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_html(format = DEFAULT_FORMAT)
|
15
|
+
title = Kernel.format("#{currency_code} %0.#{currency.subunit}f", amount)
|
16
|
+
%(<data class='money' title='#{title}'>#{to_s(format: format)}</data>)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_i
|
20
|
+
amount.to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_json(*_args)
|
24
|
+
subunit = currency.subunit
|
25
|
+
Kernel.format(
|
26
|
+
%({"currency": "#{currency_code}", "amount": "%0.#{subunit}f"}),
|
27
|
+
amount
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_r
|
32
|
+
amount
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s(format: '%<symbol>s%<amount>f', delimiter: false, separator: '.')
|
36
|
+
format = format.gsub(/%<amount>(\+?\d*)f/,
|
37
|
+
"%<amount>\\1.#{currency.subunit}f")
|
38
|
+
formatted = Kernel.format(format, amount: amount, currency: currency_code,
|
39
|
+
symbol: currency.symbol)
|
40
|
+
if delimiter
|
41
|
+
# Thanks Money gem for the regular expression
|
42
|
+
formatted.gsub!(/(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/, "\\1#{delimiter}")
|
43
|
+
end
|
44
|
+
formatted.tr!('.', separator) if separator != '.'
|
45
|
+
formatted
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
# Money is a value object for monetary values
|
5
|
+
# Money is immutable
|
6
|
+
class Money
|
7
|
+
DEFAULT_FORMAT = '%<symbol>s%<amount>f'
|
8
|
+
|
9
|
+
attr_reader :amount, :currency
|
10
|
+
|
11
|
+
def initialize(amount, currency)
|
12
|
+
raise ArgumentError, 'amount must be Numeric' unless amount.is_a?(Numeric)
|
13
|
+
|
14
|
+
unless currency.is_a?(Currency)
|
15
|
+
raise ArgumentError,
|
16
|
+
'currency must be a Currency object'
|
17
|
+
end
|
18
|
+
|
19
|
+
@amount = amount.to_r.round(currency.subunit)
|
20
|
+
@currency = currency
|
21
|
+
end
|
22
|
+
|
23
|
+
def currency_code
|
24
|
+
currency.code
|
25
|
+
end
|
26
|
+
|
27
|
+
def mint(new_amount)
|
28
|
+
new_amount.to_r == amount ? self : Money.new(new_amount, currency)
|
29
|
+
end
|
30
|
+
|
31
|
+
def inspect
|
32
|
+
Kernel.format "[#{currency_code} %0.#{currency.subunit}f]", amount
|
33
|
+
end
|
34
|
+
|
35
|
+
def same_currency?(other)
|
36
|
+
other.respond_to?(:currency) && other.currency == currency
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/minting.rb
ADDED
data/minting.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'minting/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'minting'
|
7
|
+
s.summary = 'Library to manipulate currency values'
|
8
|
+
s.description = s.summary
|
9
|
+
s.homepage = 'https://github.com/gferraz/minting'
|
10
|
+
s.version = Minting::VERSION
|
11
|
+
s.authors = ['Gilson Ferraz']
|
12
|
+
s.email = []
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
# Prevent pushing this gem to RubyGems.org.
|
16
|
+
# To allow pushes either set the 'allowed_push_host' to allow pushing to
|
17
|
+
# a single host or delete this section to allow pushing to any host.
|
18
|
+
raise 'RubyGems 3.0 or newer is required' unless s.respond_to?(:metadata)
|
19
|
+
|
20
|
+
s.metadata = {
|
21
|
+
'bug_tracker_uri' => "#{s.homepage}/issues",
|
22
|
+
'changelog_uri' => "#{s.homepage}/blob/master/CHANGELOG.md",
|
23
|
+
'homepage_uri' => s.homepage,
|
24
|
+
'source_code_uri' => s.homepage,
|
25
|
+
'allowed_push_host' => 'https://rubygems.org',
|
26
|
+
'rubygems_mfa_required' => 'true'
|
27
|
+
}
|
28
|
+
|
29
|
+
s.required_ruby_version = '>= 3.0.0'
|
30
|
+
|
31
|
+
s.files = Dir.glob('{bin,doc,lib}/**/*')
|
32
|
+
s.files += %w[minting.gemspec Rakefile README.md]
|
33
|
+
|
34
|
+
s.bindir = 'bin'
|
35
|
+
s.require_paths = ['lib']
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minting
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gilson Ferraz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-05-22 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Library to manipulate currency values
|
14
|
+
email: []
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- README.md
|
20
|
+
- Rakefile
|
21
|
+
- bin/console
|
22
|
+
- bin/setup
|
23
|
+
- lib/minting.rb
|
24
|
+
- lib/minting/currency.rb
|
25
|
+
- lib/minting/mint.rb
|
26
|
+
- lib/minting/mint/currency.rb
|
27
|
+
- lib/minting/mint/refinements.rb
|
28
|
+
- lib/minting/mint/registry.rb
|
29
|
+
- lib/minting/money.rb
|
30
|
+
- lib/minting/money/allocation.rb
|
31
|
+
- lib/minting/money/arithmetics.rb
|
32
|
+
- lib/minting/money/coercion.rb
|
33
|
+
- lib/minting/money/comparable.rb
|
34
|
+
- lib/minting/money/conversion.rb
|
35
|
+
- lib/minting/money/money.rb
|
36
|
+
- lib/minting/version.rb
|
37
|
+
- minting.gemspec
|
38
|
+
homepage: https://github.com/gferraz/minting
|
39
|
+
licenses:
|
40
|
+
- MIT
|
41
|
+
metadata:
|
42
|
+
bug_tracker_uri: https://github.com/gferraz/minting/issues
|
43
|
+
changelog_uri: https://github.com/gferraz/minting/blob/master/CHANGELOG.md
|
44
|
+
homepage_uri: https://github.com/gferraz/minting
|
45
|
+
source_code_uri: https://github.com/gferraz/minting
|
46
|
+
allowed_push_host: https://rubygems.org
|
47
|
+
rubygems_mfa_required: 'true'
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 3.0.0
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubygems_version: 3.5.9
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: Library to manipulate currency values
|
67
|
+
test_files: []
|