Class: Latinum::Bank

Inherits:
Object
  • Object
show all
Defined in:
lib/latinum/bank.rb

Overview

A bank defines exchange rates and formatting rules for resources. It is a centralised location for resource related state.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*imports) ⇒ Bank

Imports all given currencies.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/latinum/bank.rb', line 39

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

#currenciesObject (readonly)

Returns the value of attribute currencies.



80
81
82
# File 'lib/latinum/bank.rb', line 80

def currencies
  @currencies
end

#ratesObject (readonly)

Returns the value of attribute rates.



78
79
80
# File 'lib/latinum/bank.rb', line 78

def rates
  @rates
end

#symbolsObject (readonly)

Returns the value of attribute symbols.



79
80
81
# File 'lib/latinum/bank.rb', line 79

def symbols
  @symbols
end

Instance Method Details

#<<(rate) ⇒ Object

Add an exchange rate to the bank.



83
84
85
86
87
88
# File 'lib/latinum/bank.rb', line 83

def << rate
	@rates << rate
	
	@exchange[rate.input] ||= {}
	@exchange[rate.input][rate.output] = rate
end

#[](name) ⇒ Object

Look up a currency by name.



74
75
76
# File 'lib/latinum/bank.rb', line 74

def [] name
	@currencies[name]
end

#exchange(resource, for_name) ⇒ Object

Exchange one resource for another using internally specified rates.

Raises:

  • (ArgumentError)


91
92
93
94
95
96
97
98
# File 'lib/latinum/bank.rb', line 91

def exchange(resource, for_name)
	rate = @exchange[resource.name][for_name] rescue nil
	raise ArgumentError.new("Rate #{rate} unavailable") if rate == nil
	
	config = self[for_name]
	
	resource.exchange(rate.factor, for_name, config[:precision])
end

#format(resource, *args) ⇒ Object

Format a resource as a string according to the loaded currencies.

Raises:

  • (ArgumentError)


126
127
128
129
130
131
# File 'lib/latinum/bank.rb', line 126

def format(resource, *args)
	formatter = @formatters[resource.name]
	raise ArgumentError.new("No formatter found for #{resource.name}") unless formatter
	
	formatter.format(resource.amount, *args)
end

#from_integral(amount, resource_name) ⇒ Object

Convert the resource from an integral representation based on the currency’s precision.



141
142
143
144
145
# File 'lib/latinum/bank.rb', line 141

def from_integral(amount, resource_name)
	formatter = @formatters[resource_name]
	
	Resource.new(formatter.from_integral(amount), resource_name)
end

#import(resources) ⇒ Object

Import a list of resource templates, e.g. currencies.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/latinum/bank.rb', line 56

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.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/latinum/bank.rb', line 101

def parse(string, default_name: nil)
	parts = string.strip.split(/\s+/, 2)
	
	if parts.size == 2
		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 || default_name
		
		if symbol
			Resource.new(string.gsub(/[^\.0-9]/, ''), symbol.last.to_s)
		else
			raise ArgumentError.new("Could not parse #{string}, could not determine currency!")
		end
	end
end

#round(resource) ⇒ Object

Raises:

  • (ArgumentError)


118
119
120
121
122
123
# File 'lib/latinum/bank.rb', line 118

def round(resource)
	formatter = @formatters[resource.name]
	raise ArgumentError.new("No formatter found for #{resource.name}") unless formatter
	
	Latinum::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.



134
135
136
137
138
# File 'lib/latinum/bank.rb', line 134

def to_integral(resource)
	formatter = @formatters[resource.name]
	
	formatter.to_integral(resource.amount)
end