changer 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/changer.rb +129 -0
  3. data/lib/currency.rb +20 -0
  4. metadata +44 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a04bf27e78f856d6c45d8f3f8639551f56f57e03bc4c09dd7ced3754aa320662
4
+ data.tar.gz: '0694e591660881748a5c46ed6e71eaceaacd7c735a9e2847197b773454e87145'
5
+ SHA512:
6
+ metadata.gz: 694efe6c7b92307c355e8a63497e160bec6ab6293e1efb0e75956c2bd2f78f46079a040bfcca06554a82d126cca19b1b417b1e8bc4c3dfaff3d3ece09113649d
7
+ data.tar.gz: 443dc2a2aff19868c36ef673b8f7d463f281fdc1089acb9554896175ae5265a6b2d4659358818f06735c87bd7b13ecebacce76ad357fcd4cea757c4865c29e9e
@@ -0,0 +1,129 @@
1
+ require_relative 'currency'
2
+ class Currency
3
+ attr_accessor :value
4
+ attr_reader :type
5
+ TYPES = [:usd, :eur, :jpy, :gbp, :aud, :cad, :cny, :hkd, :nzd, :chf]
6
+ # Create a new Currency object
7
+ #
8
+ #
9
+ # @param to_type [Symbol]
10
+ # @param amount [Numeric]
11
+ # @return [Currency]
12
+ def initialize(to_type, amount)
13
+ raise ArgumentError.new("Invalid type or value") unless verify_valid?(to_type, amount)
14
+
15
+ @type = to_type
16
+ @value = format_value(amount)
17
+ end
18
+ # Manually set a new value for a Currency object
19
+ # @param amount [Numeric]
20
+ def value=(amount)
21
+ raise ArgumentError.new("Amount must be a non-negative numeric value") unless amount.is_a?(Numeric) && amount >= 0
22
+
23
+ @value = amount.to_f
24
+ end
25
+ # Convert a currency to another type using market rates
26
+ # @param to_type [Symbol]
27
+ # @return [Currency] || nil if invalid
28
+ def convert(to_type)
29
+ return nil unless TYPES.include?(to_type)
30
+
31
+ new_value = value * Currency.fetch_rate(type, to_type)
32
+ Currency.new(to_type, new_value)
33
+ end
34
+ # Convert to a different currency at a specified rate
35
+ # @param to_type [Symbol]
36
+ # @param rate [Numeric]
37
+ # @note rate is set based on the calling object as a base
38
+ def convert_at(to_type, rate)
39
+ return nil unless TYPES.include?(to_type)
40
+
41
+ new_value = value * rate
42
+ Currency.new(to_type, new_value)
43
+ end
44
+ # Convert the calling object to the currency specified by the to_type param
45
+ # @param to_type [Symbol]
46
+ def convert!(to_type)
47
+ return nil unless TYPES.include?(to_type)
48
+
49
+ self.value = value * Currency.fetch_rate(type, to_type)
50
+ @type = to_type
51
+ self
52
+ end
53
+ # Convert the calling object to the currency specified by the to_type param
54
+ # at the rate specified by the rate parameter
55
+ # @param rate [Numeric]
56
+ def convert_at!(to_type, rate)
57
+ return nil unless TYPES.include?(to_type)
58
+
59
+ self.value = value * rate
60
+ @type = to_type
61
+ self
62
+ end
63
+ # Return the current value of the Currency object
64
+ # @return [Numeric]
65
+ def to_f
66
+ value
67
+ end
68
+ # Return a string formatted as ie; "USD 5.00"
69
+ # @return [String]
70
+ def to_s
71
+ format_string
72
+ end
73
+
74
+ # All of the math operations return values in the type of currency
75
+ # calling the method ie: USD + GBP = USD, but GBP + USD = GBP
76
+ def +(other)
77
+ first_type = self.type
78
+ new_value = (value + other.convert(first_type).value)
79
+ Currency.new(first_type, new_value)
80
+ end
81
+
82
+ def -(other)
83
+ first_type = self.type
84
+ new_value = (value - other.convert(first_type).value)
85
+ Currency.new(first_type, new_value)
86
+ end
87
+
88
+ def *(other)
89
+ first_type = self.type
90
+ new_value = (value * other.convert(first_type).value)
91
+ Currency.new(first_type, new_value)
92
+ end
93
+
94
+ def /(other)
95
+ first_type = self.type
96
+ new_value = (value / other.convert(first_type).value)
97
+ Currency.new(first_type, new_value)
98
+ end
99
+ # Fetch the current exchange rate using the from_type as the base
100
+ # @param from_type [Symbol]
101
+ # @param to_type [Symbol]
102
+ def self.fetch_rate(from_type, to_type)
103
+ changer = Changer.new(from_type, to_type)
104
+ changer.rate
105
+ end
106
+
107
+ private
108
+
109
+ def format_string
110
+ amount = add_commas(format("%.2f",value))
111
+ "#{type.to_s.upcase} #{amount}"
112
+ end
113
+
114
+ def format_value(value)
115
+ value.to_f
116
+ end
117
+
118
+ def verify_valid?(to_type, amount)
119
+ return false unless amount.is_a?(Numeric) && to_type.is_a?(Symbol)
120
+
121
+ amount >= 0.0 && TYPES.include?(to_type)
122
+ end
123
+
124
+ def add_commas(number)
125
+ first, last = number.to_s.split('.')
126
+ first.reverse.chars.each_slice(3).to_a
127
+ .map(&:join).join(',').reverse + '.' + last
128
+ end
129
+ end
@@ -0,0 +1,20 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'openssl'
4
+ require 'json'
5
+
6
+ class Changer
7
+ attr_reader :rate
8
+
9
+ def initialize(from_type, to_type)
10
+ from_type = from_type.to_s.upcase
11
+ to_type = to_type.to_s.upcase
12
+ url = URI("https://api.exchangeratesapi.io/latest?base=#{from_type}")
13
+ http = Net::HTTP.new(url.host, url.port)
14
+ http.use_ssl = true
15
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
16
+ request = Net::HTTP::Get.new(url)
17
+ response = http.request(request)
18
+ @rate = JSON.parse(response.read_body)["rates"]["#{to_type}"].to_f
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: changer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Jordan Whistler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Create currency objects for easy conversion and calculations
14
+ email: jordan_0_0_7@yahoo.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/changer.rb
20
+ - lib/currency.rb
21
+ homepage: https://rubygems.org/gems/changer
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubygems_version: 3.1.2
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: A gem for creating currency objects
44
+ test_files: []