amount 1.0.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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +31 -0
  3. data/lib/amount/version.rb +18 -0
  4. data/lib/amount.rb +157 -0
  5. metadata +62 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 13044725c9fe6a8d41d0b7984ad962deec866d8a3674031bd9de40a91cdaa5be
4
+ data.tar.gz: 7e433ccc610c7b8e943f9ef60c7d8a36d9d3d8152d5ff190e351de6001e27a48
5
+ SHA512:
6
+ metadata.gz: 60e119fe8ed12781242f6e6125f54d22503af83120d329eb42424332fe96b9d7a71bc96883d5fbcc0d1c2fc877fa5cce8c10716416dde2113b0355bb3b91c267
7
+ data.tar.gz: cf975eb171b90104205856acd2bb3a1f7e047d3296136067bc9a602ca4f96bd298b5d8735c6e5c62f5d321cd9c8cd5ee21cce7674485f8a97329797d1baa01d0
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Amount
2
+
3
+ The amount gem provides a class called `Amount` that represents an amount of money with currency and 18-digit precision. It extends the functionality of the fixed gem and adds currency support to handle monetary values accurately.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'amount'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install amount
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/akuhn/amount](https://github.com/akuhn/amount). This project encourages collaboration and appreciates contributions. Feel free to contribute to the project by reporting bugs or submitting pull requests.
28
+
29
+ ## License
30
+
31
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Amount < Fixed
4
+ VERSION = "1.0.0"
5
+ end
6
+
7
+
8
+ __END__
9
+
10
+ # Major version bump when breaking changes or new features
11
+ # Minor version bump when backward-compatible changes or enhancements
12
+ # Patch version bump when backward-compatible bug fixes, security updates etc
13
+
14
+ 1.0.0
15
+
16
+ - Extends the fixed gem
17
+ - Adds currency support to handle monetary values
18
+ - Convenient constructors for creating money amounts
data/lib/amount.rb ADDED
@@ -0,0 +1,157 @@
1
+ require 'fixed'
2
+ require 'amount/version'
3
+
4
+ # An amount of money with currency and 18-digit precision.
5
+
6
+
7
+ class Amount < Fixed
8
+
9
+ attr_reader :currency
10
+
11
+
12
+ #------- constructors ---------------------------------------------
13
+
14
+ private_class_method :new
15
+
16
+ def initialize(currency, fractions)
17
+ raise unless Symbol === currency
18
+ @currency = currency
19
+ super fractions
20
+ end
21
+
22
+ def self.create(value, currency = nil)
23
+ if currency.nil?
24
+ case value
25
+ when Amount
26
+ return value
27
+ when String
28
+ return self.parse(value)
29
+ when Hash
30
+ case value.size
31
+ when 1
32
+ currency, value = value.first
33
+ when 2
34
+ return Amount.create value.fetch(:amount), value.fetch(:currency)
35
+ else
36
+ raise ArgumentError, "expected amount, got #{value.inspect}"
37
+ end
38
+ end
39
+ end
40
+
41
+ case value
42
+ when String
43
+ new currency.to_sym, string_as_fractions(value)
44
+ when Fixed
45
+ new currency.to_sym, value.fractions
46
+ when Numeric
47
+ new currency.to_sym, number_as_fractions(value)
48
+ else
49
+ raise ArgumentError, "expected amount, got #{[value,currency].inspect}"
50
+ end
51
+ end
52
+
53
+ def self.parse(string)
54
+ raise "expect amount and currency, got #{string.inspect}" unless string =~ /\A(\S+)\s+(\S+)\Z/
55
+ new $2.to_sym, string_as_fractions($1)
56
+ end
57
+
58
+ def self.from_number(currency, units)
59
+ new currency, number_as_fractions(units)
60
+ end
61
+
62
+ def self.from_fractions(currency, fractions, precision: nil)
63
+ if precision
64
+ raise unless (0..18) === precision
65
+ fractions = fractions * (10 ** (18 - precision))
66
+ end
67
+
68
+ new currency, fractions
69
+ end
70
+
71
+ def self.smallest(currency)
72
+ new currency, 1
73
+ end
74
+
75
+ def self.zero(currency)
76
+ new currency, 0
77
+ end
78
+
79
+ #------- arithmetics ----------------------------------------------
80
+
81
+ def +(amount)
82
+ raise "expected curreny #{self.currency}, got #{amount.currency}" unless self.currency == amount.currency
83
+ super
84
+ end
85
+
86
+ def -(amount)
87
+ raise "expected curreny #{self.currency}, got #{amount.currency}" unless self.currency == amount.currency
88
+ super
89
+ end
90
+
91
+ def *(number)
92
+ raise "expected curreny #{self.currency}, got #{number.currency}" unless self.currency == number.currency if Amount === number
93
+ super
94
+ end
95
+
96
+ def /(number)
97
+ raise "expected curreny #{self.currency}, got #{number.currency}" unless self.currency == number.currency if Amount === number
98
+ super
99
+ end
100
+
101
+
102
+ # ------- comparing -----------------------------------------------
103
+
104
+ def dollar?
105
+ self.currency == :USD
106
+ end
107
+
108
+ def ==(amount)
109
+ Amount === amount && self.currency == amount.currency && self.fractions == amount.fractions
110
+ end
111
+
112
+
113
+ # ------- printing ------------------------------------------------
114
+
115
+ def inspect
116
+ "#{super} #{currency}"
117
+ end
118
+
119
+ def format(precision = 8)
120
+ "#{super precision} #{currency}"
121
+ end
122
+
123
+
124
+ # ------- helpers -------------------------------------------------
125
+
126
+ def to_amount
127
+ self
128
+ end
129
+
130
+ def eps
131
+ self.fractions
132
+ end
133
+
134
+ def without_currency
135
+ Fixed.from_fractions self.fractions
136
+ end
137
+
138
+ protected
139
+
140
+ def make(new_fractions)
141
+ Amount.from_fractions self.currency, new_fractions
142
+ end
143
+
144
+ end
145
+
146
+ module Kernel
147
+ def Amount(value, currency = nil)
148
+ Amount.create value, currency
149
+ end
150
+ end
151
+
152
+ class String
153
+ def to_amount
154
+ Amount.parse self
155
+ end
156
+ end
157
+
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: amount
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Adrian Kuhn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fixed
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ description:
28
+ email:
29
+ - akuhn@iam.unibe.ch
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - README.md
35
+ - lib/amount.rb
36
+ - lib/amount/version.rb
37
+ homepage: https://github.com/akuhn/amount
38
+ licenses: []
39
+ metadata:
40
+ homepage_uri: https://github.com/akuhn/amount
41
+ source_code_uri: https://github.com/akuhn/amount
42
+ changelog_uri: https://github.com/akuhn/amount/blob/master/lib/amount/version.rb
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 2.6.0
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubygems_version: 3.1.6
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: An amount of money with currency and 18-digit precision.
62
+ test_files: []