minting 1.0.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4dfd2f98840b009208b9cccab86e9ca5d093300351e9e2031e70e03b93315638
4
- data.tar.gz: 47a92df548558e20fd7bea3caa10a8966db91341d998e9712405af3d97fe12ae
3
+ metadata.gz: e2e9f992fc49846276b49db3b06639ed38a2037dceb3762ffac27d1bc03b4d37
4
+ data.tar.gz: 12fdb933a6cd61b2fa2dc61455ac3932f71fdd7822dd04261d5b0b8ec0fa4ba8
5
5
  SHA512:
6
- metadata.gz: 175607c53124f16cac60c699a6ed6f042b3c3e960055bca1ccb7ba822a05b6cf8401fb66902e148a9ed50b43524ce6e708feaa72cac15f6ddd8b9cf3e9189cc6
7
- data.tar.gz: 4fc09433abd38014d0d99c16aed5f88eb36ad039e422b0ffa305d3335da1753a23bae2bfcf775ce6142edf844463ed3942710d87f034375f99e04ff1b7e92812
6
+ metadata.gz: 3013fca2971566d9503f2375aa1330f191e3467cdd2c442d92a83cd5b493e2778a7ef97dfc6248166af9be4002990a31eb2cbd3df38dcd1508407e12829d2515
7
+ data.tar.gz: ff7261f4c1fd93586833feb391fd8c95c90a1c1de7f6d5410a4ba406d40f4fcb536684e01ecbd725c87a1c9ef53caa29371a17bf05a6fc7d65320f5c255bb39b
data/README.md CHANGED
@@ -33,7 +33,7 @@ total.currency_code #=> "USD"
33
33
 
34
34
  - Arithmetic: `+ - * /`, unary minus, `abs`
35
35
  - Comparisons: `==`, `<=>`, `zero?`, `nonzero?`, `positive?`, `negative?`
36
- - Formatting: `to_s` with custom formats, delimiters, separators
36
+ - Formatting: `to_s` with custom formats, thousand delimiters and decimal separators
37
37
  - Serialization: `to_json`, `to_i`, `to_f`, `to_r`, `to_d`
38
38
  - Allocation utilities: `split(quantity)`, `allocate([ratios])`
39
39
  - Numeric Refinements for ergonomics: `10.dollars`, `3.euros`, `4.to_money('USD')`
@@ -2,7 +2,7 @@
2
2
  module Mint
3
3
  def self.money(amount, currency_code)
4
4
  currency = currency(currency_code)
5
- return Money.new(amount, currency) if currency
5
+ return Money.new(amount, currency).freeze if currency
6
6
 
7
7
  available = currencies.keys.join(', ')
8
8
  raise ArgumentError, "Currency [#{currency_code}] not registered. Available: #{available}"
@@ -29,18 +29,5 @@ module Mint
29
29
  def to_r
30
30
  amount
31
31
  end
32
-
33
- def to_s(format: '%<symbol>s%<amount>f', delimiter: false, separator: '.')
34
- format = format.gsub(/%<amount>(\+?\d*)f/,
35
- "%<amount>\\1.#{currency.subunit}f")
36
- formatted = Kernel.format(format, amount: amount, currency: currency_code,
37
- symbol: currency.symbol)
38
- if delimiter
39
- # Thanks Money gem for the regular expression
40
- formatted.gsub!(/(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/, "\\1#{delimiter}")
41
- end
42
- formatted.tr!('.', separator) if separator != '.'
43
- formatted
44
- end
45
32
  end
46
33
  end
@@ -0,0 +1,69 @@
1
+ module Mint
2
+ # Formatting functionality for Money objects
3
+ class Money
4
+ # Formats money as a string with customizable format, thousand delimiter, and decimal
5
+ #
6
+ # @param format [String] Format string with placeholders: %<symbol>s, %<amount>f, %<currency>s
7
+ # @param thousand [String, false] Thousands delimiter (e.g., ',' for 1,000)
8
+ # @param decimal [String] Decimal separator (e.g., '.' or ',')
9
+ # @return [String] Formatted money string
10
+ #
11
+ # @example Basic formatting
12
+ # money = Mint.money(1234.56, 'USD')
13
+ # money.to_s #=> "$1234.56"
14
+ # money.to_s(thousand: ',') #=> "$1,234.56"
15
+ # money.to_s(decimal: ',') #=> "$1234,56"
16
+ #
17
+ # @example Custom formats
18
+ # money.to_s(format: '%<amount>f') #=> "1234.56"
19
+ # money.to_s(format: '%<currency>s %<amount>f') #=> "USD 1234.56"
20
+ # money.to_s(format: '%<amount>f %<symbol>s') #=> "1234.56 $"
21
+ # money.to_s(format: '%<symbol>s%<amount>+f') #=> "$+1234.56"
22
+ #
23
+ # @example Padding and alignment
24
+ # money.to_s(format: '%<amount>10.2f') #=> " 1234.56"
25
+ # money.to_s(format: '%<symbol>s%<amount>010.2f') #=> "$0001234.56"
26
+ #
27
+ def to_s(format: '%<symbol>s%<amount>f', decimal: '.', thousand: ',', width: nil)
28
+ raise ArgumentError, 'Invalid format' unless format.is_a?(String) || format.is_a?(Hash)
29
+
30
+ formatted = format_amount(format)
31
+
32
+ formatted.tr!('.', decimal) if decimal != '.'
33
+
34
+ unless thousand.empty?
35
+ # Regular expression courtesy of Money gem
36
+ # Matches digits followed by groups of 3 digits until non-digit or end
37
+ formatted.gsub!(/(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/, "\\1#{thousand}")
38
+ end
39
+
40
+ formatted = formatted.rjust(width) if width
41
+ formatted
42
+ end
43
+
44
+ def format_amount(format)
45
+ # binding.irb if format.is_a? Hash
46
+ format = { positive: format } if format.is_a?(String)
47
+ value = amount
48
+
49
+ if amount.negative? && format[:negative]
50
+ format = format[:negative]
51
+ value = -amount
52
+ elsif amount.zero? && format[:zero]
53
+ format = format[:zero]
54
+ else
55
+ format = format[:positive]
56
+ end
57
+ format ||= '%<symbol>s%<amount>f'
58
+
59
+ # Automatically adjust decimal places based on currency subunit
60
+ adjusted_format = format.gsub(/%<amount>(\+?\d*)f/,
61
+ "%<amount>\\1.#{currency.subunit}f")
62
+
63
+ Kernel.format(adjusted_format,
64
+ amount: value,
65
+ currency: currency_code,
66
+ symbol: currency.symbol)
67
+ end
68
+ end
69
+ end
@@ -25,14 +25,14 @@ module Mint
25
25
  end
26
26
 
27
27
  def hash
28
- @hash ||= zero? ? 0.hash : [amount, currency.code].hash
28
+ zero? ? 0.hash : [amount, currency.code].hash
29
29
  end
30
30
 
31
31
  # Returns a new Money object with the specified amount, or self if unchanged
32
32
  # @param new_amount [Numeric] The new amount
33
33
  # @return [Money] A new Money object or self
34
34
  def mint(new_amount)
35
- new_amount.to_r == amount ? self : Money.new(new_amount, currency)
35
+ new_amount.to_r == amount ? self : Money.new(new_amount, currency).freeze
36
36
  end
37
37
 
38
38
  def inspect
data/lib/minting/money.rb CHANGED
@@ -3,4 +3,5 @@ require 'minting/money/arithmetics'
3
3
  require 'minting/money/coercion'
4
4
  require 'minting/money/comparable'
5
5
  require 'minting/money/conversion'
6
+ require 'minting/money/formatting'
6
7
  require 'minting/money/money'
@@ -1,3 +1,3 @@
1
1
  module Minting
2
- VERSION = '1.0.0'.freeze
2
+ VERSION = '1.0.1'.freeze
3
3
  end
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.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gilson Ferraz
@@ -30,6 +30,7 @@ files:
30
30
  - lib/minting/money/coercion.rb
31
31
  - lib/minting/money/comparable.rb
32
32
  - lib/minting/money/conversion.rb
33
+ - lib/minting/money/formatting.rb
33
34
  - lib/minting/money/money.rb
34
35
  - lib/minting/version.rb
35
36
  - minting.gemspec