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.



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

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.



82
83
84
# File 'lib/latinum/bank.rb', line 82

def currencies
  @currencies
end

#ratesObject (readonly)

Returns the value of attribute rates.



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

def rates
  @rates
end

#symbolsObject (readonly)

Returns the value of attribute symbols.



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

def symbols
  @symbols
end

Instance Method Details

#<<(rate) ⇒ Object

Add an exchange rate to the bank.



85
86
87
88
89
90
# File 'lib/latinum/bank.rb', line 85

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

#[](name) ⇒ Object

Look up a currency by name.



76
77
78
# File 'lib/latinum/bank.rb', line 76

def [] name
	@currencies[name]
end

#exchange(resource, for_name) ⇒ Object

Exchange one resource for another using internally specified rates.

Raises:

  • (ArgumentError)


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

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)


130
131
132
133
134
135
# File 'lib/latinum/bank.rb', line 130

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.



145
146
147
148
149
# File 'lib/latinum/bank.rb', line 145

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.



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

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.



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

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
		
		if symbol
			Resource.new(string.gsub(/[^\-\.0-9]/, ''), symbol.last.to_s)
		elsif default_name
			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

Raises:

  • (ArgumentError)


122
123
124
125
126
127
# File 'lib/latinum/bank.rb', line 122

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.



138
139
140
141
142
# File 'lib/latinum/bank.rb', line 138

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