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.
- #dump(resource) ⇒ Object
-
#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.
- #load(input) ⇒ Object
-
#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.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/latinum/bank.rb', line 37 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.
84 85 86 |
# File 'lib/latinum/bank.rb', line 84 def currencies @currencies end |
#rates ⇒ Object (readonly)
Returns the value of attribute rates.
76 77 78 |
# File 'lib/latinum/bank.rb', line 76 def rates @rates end |
#symbols ⇒ Object (readonly)
A map of all recognised symbols ordered by priority.
80 81 82 |
# File 'lib/latinum/bank.rb', line 80 def symbols @symbols end |
Instance Method Details
#<<(rate) ⇒ Object
Add an exchange rate to the bank.
88 89 90 91 92 93 |
# File 'lib/latinum/bank.rb', line 88 def <<(rate) @rates << rate @exchange[rate.input] ||= {} @exchange[rate.input][rate.output] = rate end |
#[](name) ⇒ Object
Look up a currency by name.
72 73 74 |
# File 'lib/latinum/bank.rb', line 72 def [](name) @currencies[name] end |
#dump(resource) ⇒ Object
135 136 137 |
# File 'lib/latinum/bank.rb', line 135 def dump(resource) resource.to_s if resource end |
#exchange(resource, for_name) ⇒ Object
Exchange one resource for another using internally specified rates.
96 97 98 99 100 101 102 103 104 |
# File 'lib/latinum/bank.rb', line 96 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.
160 161 162 163 164 165 166 |
# File 'lib/latinum/bank.rb', line 160 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.
181 182 183 184 185 |
# File 'lib/latinum/bank.rb', line 181 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.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/latinum/bank.rb', line 54 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 |
#load(input) ⇒ Object
128 129 130 131 132 133 |
# File 'lib/latinum/bank.rb', line 128 def load(input) if input.is_a?(String) input = input.strip return parse(input) unless input.empty? end end |
#parse(string, default_name: nil) ⇒ Object
Parse a string according to the loaded currencies.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/latinum/bank.rb', line 107 def parse(string, default_name: nil) parts = string.strip.split(/\s+/, 2) if parts.size == 2 return parse_named_resource(parts[1], parts[0]) else # Lookup the named symbol, e.g. '$', and get the highest priority name: symbol = @symbols.fetch(string.gsub(/[\-\.,0-9]/, ''), []).last if symbol name = symbol.last.to_s elsif default_name name = default_name else raise ArgumentError, "Could not parse #{string}, could not determine resource name!" end return parse_named_resource(name, string) 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.
150 151 152 153 154 155 156 |
# File 'lib/latinum/bank.rb', line 150 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.
171 172 173 174 175 |
# File 'lib/latinum/bank.rb', line 171 def to_integral(resource) formatter = @formatters[resource.name] formatter.to_integral(resource.amount) end |