redis-bank 0.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.
Files changed (4) hide show
  1. data/README.md +19 -0
  2. data/init.rb +1 -0
  3. data/lib/redis-bank.rb +152 -0
  4. metadata +64 -0
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ Redis-Bank
2
+ ==========
3
+
4
+ A Redis-backed bank for the Money gem.
5
+
6
+ Usage
7
+ -----
8
+
9
+ ```ruby
10
+ redis_client = Redis.new
11
+ # Or, if you'd rather just test it out without firing up redis,
12
+ # you can just use a hash, e.g.
13
+ # redis_client = {}
14
+ Money.bank = Money::Bank::RedisBank.new redis_client
15
+ Money.bank.add_rate("USD", "CAD", 1.24515)
16
+ Money.bank.add_rate("CAD", "USD", 0.803115)
17
+ Money.us_dollar(100).exchange_to("CAD") => Money.ca_dollar(124)
18
+ Money.ca_dollar(100).exchange_to("USD") => Money.us_dollar(80)
19
+ ```
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'redis-bank'
data/lib/redis-bank.rb ADDED
@@ -0,0 +1,152 @@
1
+ require 'money/bank/base'
2
+
3
+ class Money
4
+ module Bank
5
+ # Thrown when an unknown rate format is requested.
6
+ class UnknownRateFormat < StandardError; end
7
+
8
+ # Class for aiding in exchanging money between different currencies. By
9
+ # default, the +Money+ class uses an object of this class (accessible
10
+ # through +Money#bank+) for performing currency exchanges.
11
+ #
12
+ # @example
13
+ # bank = Money::Bank::RedisBank.new redis_client
14
+ # bank.add_rate("USD", "CAD", 1.24515)
15
+ # bank.add_rate("CAD", "USD", 0.803115)
16
+ #
17
+ # c1 = 100_00.to_money("USD")
18
+ # c2 = 100_00.to_money("CAD")
19
+ #
20
+ # # Exchange 100 USD to CAD:
21
+ # bank.exchange_with(c1, "CAD") #=> #<Money @cents=1245150>
22
+ #
23
+ # # Exchange 100 CAD to USD:
24
+ # bank.exchange_with(c2, "USD") #=> #<Money @cents=803115>
25
+ class RedisBank < Base
26
+
27
+ def initialize(redis_client, &block)
28
+ super(&block)
29
+ @redis_client = redis_client
30
+ end
31
+
32
+ # Exchanges the given +Money+ object to a new +Money+ object in
33
+ # +to_currency+.
34
+ #
35
+ # @param [Money] from
36
+ # The +Money+ object to exchange.
37
+ # @param [Currency, String, Symbol] to_currency
38
+ # The currency to exchange to.
39
+ #
40
+ # @yield [n] Optional block to use when rounding after exchanging one
41
+ # currency for another.
42
+ # @yieldparam [Float] n The resulting float after exchanging one currency
43
+ # for another.
44
+ # @yieldreturn [Integer]
45
+ #
46
+ # @return [Money]
47
+ #
48
+ # @raise +Money::Bank::UnknownRate+ if the conversion rate is unknown.
49
+ #
50
+ # @example
51
+ # bank = Money::Bank::RedisBank.new redis_client
52
+ # bank.add_rate("USD", "CAD", 1.24515)
53
+ # bank.add_rate("CAD", "USD", 0.803115)
54
+ #
55
+ # c1 = 100_00.to_money("USD")
56
+ # c2 = 100_00.to_money("CAD")
57
+ #
58
+ # # Exchange 100 USD to CAD:
59
+ # bank.exchange_with(c1, "CAD") #=> #<Money @cents=1245150>
60
+ #
61
+ # # Exchange 100 CAD to USD:
62
+ # bank.exchange_with(c2, "USD") #=> #<Money @cents=803115>
63
+ def exchange_with(from, to_currency)
64
+ return from if same_currency?(from.currency, to_currency)
65
+
66
+ rate = get_rate(from.currency, to_currency)
67
+ unless rate
68
+ raise UnknownRate, "No conversion rate known for '#{from.currency.iso_code}' -> '#{to_currency}'"
69
+ end
70
+ _to_currency_ = Currency.wrap(to_currency)
71
+
72
+ cents = BigDecimal.new(from.cents.to_s) / (BigDecimal.new(from.currency.subunit_to_unit.to_s) / BigDecimal.new(_to_currency_.subunit_to_unit.to_s))
73
+
74
+ ex = cents * BigDecimal.new(rate.to_s)
75
+ ex = ex.to_f
76
+ ex = if block_given?
77
+ yield ex
78
+ elsif @rounding_method
79
+ @rounding_method.call(ex)
80
+ else
81
+ ex.to_s.to_i
82
+ end
83
+ Money.new(ex, _to_currency_)
84
+ end
85
+
86
+ # Registers a conversion rate and returns it (uses +#set_rate+).
87
+ #
88
+ # @param [Currency, String, Symbol] from Currency to exchange from.
89
+ # @param [Currency, String, Symbol] to Currency to exchange to.
90
+ # @param [Numeric] rate Rate to use when exchanging currencies.
91
+ #
92
+ # @return [Numeric]
93
+ #
94
+ # @example
95
+ # bank = Money::Bank::VariableExchange.new
96
+ # bank.add_rate("USD", "CAD", 1.24515)
97
+ # bank.add_rate("CAD", "USD", 0.803115)
98
+ def add_rate(from, to, rate)
99
+ set_rate(from, to, rate)
100
+ end
101
+
102
+ # Set the rate for the given currencies. Uses +Mutex+ to synchronize data
103
+ # access.
104
+ #
105
+ # @param [Currency, String, Symbol] from Currency to exchange from.
106
+ # @param [Currency, String, Symbol] to Currency to exchange to.
107
+ # @param [Numeric] rate Rate to use when exchanging currencies.
108
+ #
109
+ # @return [Numeric]
110
+ #
111
+ # @example
112
+ # bank = Money::Bank::VariableExchange.new
113
+ # bank.set_rate("USD", "CAD", 1.24515)
114
+ # bank.set_rate("CAD", "USD", 0.803115)
115
+ def set_rate(from, to, rate)
116
+ @redis_client[rate_key_for(from, to)] = rate
117
+ end
118
+
119
+ # Retrieve the rate for the given currencies. Uses +Mutex+ to synchronize
120
+ # data access.
121
+ #
122
+ # @param [Currency, String, Symbol] from Currency to exchange from.
123
+ # @param [Currency, String, Symbol] to Currency to exchange to.
124
+ #
125
+ # @return [Numeric]
126
+ #
127
+ # @example
128
+ # bank = Money::Bank::VariableExchange.new
129
+ # bank.set_rate("USD", "CAD", 1.24515)
130
+ # bank.set_rate("CAD", "USD", 0.803115)
131
+ #
132
+ # bank.get_rate("USD", "CAD") #=> 1.24515
133
+ # bank.get_rate("CAD", "USD") #=> 0.803115
134
+ def get_rate(from, to)
135
+ @redis_client[rate_key_for(from, to)]
136
+ end
137
+
138
+ # Return the rate hashkey for the given currencies.
139
+ #
140
+ # @param [Currency, String, Symbol] from The currency to exchange from.
141
+ # @param [Currency, String, Symbol] to The currency to exchange to.
142
+ #
143
+ # @return [String]
144
+ #
145
+ # @example
146
+ # rate_key_for("USD", "CAD") #=> "USD_TO_CAD"
147
+ def rate_key_for(from, to)
148
+ "#{Currency.wrap(from).iso_code}_TO_#{Currency.wrap(to).iso_code}".upcase
149
+ end
150
+ end
151
+ end
152
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis-bank
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Cameron Walsh
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-06-08 00:00:00 +10:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Redis-backed Bank for the Money gem based on the VariableExchangeBank
22
+ email: cameron.walsh@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - README.md
31
+ - init.rb
32
+ - lib/redis-bank.rb
33
+ has_rdoc: true
34
+ homepage: ""
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.6
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Redis-backed Bank for the Money gem
63
+ test_files: []
64
+