Class: Latinum::Bank
- Inherits:
-
Object
- Object
- Latinum::Bank
- Defined in:
- lib/latinum/bank.rb
Overview
A bank defines exchange rates and formatting rules for resources. It is a centralised location for resource formatting and metadata.
Instance Attribute Summary collapse
-
#currencies ⇒ Object
readonly
The supported currents and assocaited formatting details.
-
#rates ⇒ Object
readonly
Returns the value of attribute rates.
-
#symbols ⇒ Object
readonly
A map of all recognised symbols ordered by priority.
Instance Method Summary collapse
-
#<<(rate) ⇒ Object
Add an exchange rate to the bank.
-
#[](name) ⇒ Object
Look up a currency by name.
-
#exchange(resource, for_name) ⇒ Object
Exchange one resource for another using internally specified rates.
-
#format(resource, *arguments, **options) ⇒ Object
Format a resource as a string according to the loaded currencies.
-
#from_integral(amount, name) ⇒ Object
Convert the resource from an integral representation based on the currency’s precision.
-
#import(resources) ⇒ Object
Import a list of resource templates, e.g.
-
#initialize(*imports) ⇒ Bank
constructor
Imports all given currencies.
-
#parse(string, default_name: nil) ⇒ Object
Parse a string according to the loaded currencies.
-
#round(resource) ⇒ Object
Rounds the specified resource to the maximum precision as specified by the formatter.
-
#to_integral(resource) ⇒ Object
Convert the resource to an integral representation based on the currency’s precision.
Constructor Details
#initialize(*imports) ⇒ Bank
Imports all given currencies.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/latinum/bank.rb', line 53 def initialize(*imports) @rates = [] @exchange = {} # This implementation may change: @currencies = {} @formatters = {} # Symbols and their associated priorities @symbols = {} imports.each do |resources| import(resources) end end |
Instance Attribute Details
#currencies ⇒ Object (readonly)
The supported currents and assocaited formatting details.
100 101 102 |
# File 'lib/latinum/bank.rb', line 100 def currencies @currencies end |
#rates ⇒ Object (readonly)
Returns the value of attribute rates.
92 93 94 |
# File 'lib/latinum/bank.rb', line 92 def rates @rates end |
#symbols ⇒ Object (readonly)
A map of all recognised symbols ordered by priority.
96 97 98 |
# File 'lib/latinum/bank.rb', line 96 def symbols @symbols end |
Instance Method Details
#<<(rate) ⇒ Object
Add an exchange rate to the bank.
104 105 106 107 108 109 |
# File 'lib/latinum/bank.rb', line 104 def <<(rate) @rates << rate @exchange[rate.input] ||= {} @exchange[rate.input][rate.output] = rate end |
#[](name) ⇒ Object
Look up a currency by name.
88 89 90 |
# File 'lib/latinum/bank.rb', line 88 def [](name) @currencies[name] end |
#exchange(resource, for_name) ⇒ Object
Exchange one resource for another using internally specified rates.
112 113 114 115 116 117 118 119 120 |
# File 'lib/latinum/bank.rb', line 112 def exchange(resource, for_name) unless rate = @exchange.dig(resource.name, for_name) raise ArgumentError.new("Rate #{rate} unavailable") end config = self[for_name] return resource.exchange(rate.factor, for_name, config[:precision]) end |
#format(resource, *arguments, **options) ⇒ Object
Format a resource as a string according to the loaded currencies.
155 156 157 158 159 160 161 |
# File 'lib/latinum/bank.rb', line 155 def format(resource, *arguments, **) unless formatter = @formatters[resource.name] raise ArgumentError.new("No formatter found for #{resource.name}") end formatter.format(resource.amount, *arguments, **) end |
#from_integral(amount, name) ⇒ Object
Convert the resource from an integral representation based on the currency’s precision.
176 177 178 179 180 |
# File 'lib/latinum/bank.rb', line 176 def from_integral(amount, name) formatter = @formatters[name] Resource.new(formatter.from_integral(amount), name) end |
#import(resources) ⇒ Object
Import a list of resource templates, e.g. currencies.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/latinum/bank.rb', line 70 def import(resources) resources.each do |name, config| name = (config[:name] || name).to_s @currencies[name] = config # Create a formatter: @formatters[name] = config[:formatter].new(**config) if config[:symbol] symbols = (@symbols[config[:symbol]] ||= []) symbols << [config.fetch(:priority, -1), name.to_s] symbols.sort!.uniq! end end end |
#parse(string, default_name: nil) ⇒ Object
Parse a string according to the loaded currencies.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/latinum/bank.rb', line 123 def parse(string, default_name: nil) parts = string.strip.split(/\s+/, 2) if parts.size == 2 return Resource.new(parts[0].gsub(/[^\-\.0-9]/, ''), parts[1]) else # Lookup the named symbol, e.g. '$', and get the highest priority name: symbol = @symbols.fetch(string.gsub(/[\-\.,0-9]/, ''), []).last if symbol return Resource.new(string.gsub(/[^\-\.0-9]/, ''), symbol.last.to_s) elsif default_name return Resource.new(string.gsub(/[^\-\.0-9]/, ''), default_name.to_s) else raise ArgumentError.new("Could not parse #{string}, could not determine currency!") end end end |
#round(resource) ⇒ Object
Rounds the specified resource to the maximum precision as specified by the formatter. Whe computing things like tax, you often get fractional amounts which are unpayable because they are smaller than the minimum discrete unit of the currency. This method helps to round a currency to a payable amount.
145 146 147 148 149 150 151 |
# File 'lib/latinum/bank.rb', line 145 def round(resource) unless formatter = @formatters[resource.name] raise ArgumentError.new("No formatter found for #{resource.name}") end return Resource.new(formatter.round(resource.amount), resource.name) end |
#to_integral(resource) ⇒ Object
Convert the resource to an integral representation based on the currency’s precision.
166 167 168 169 170 |
# File 'lib/latinum/bank.rb', line 166 def to_integral(resource) formatter = @formatters[resource.name] formatter.to_integral(resource.amount) end |