redis-bank 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+