Skip to content

Commit ef6d211

Browse files
committed
Explicit US locale when decoding
1 parent af77755 commit ef6d211

File tree

4 files changed

+52
-33
lines changed

4 files changed

+52
-33
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// KeyedDecodingContainer+DecodeUS.swift
3+
//
4+
//
5+
// Created by Adam Borbas on 26/03/2024.
6+
//
7+
8+
import Foundation
9+
10+
extension KeyedDecodingContainer {
11+
private var numberFormatter: NumberFormatter {
12+
let numberFormatter = NumberFormatter()
13+
numberFormatter.numberStyle = .decimal
14+
numberFormatter.locale = Locale(identifier: "en-US")
15+
return numberFormatter
16+
}
17+
18+
func decodeUSDecimal(forKey key: K) throws -> Decimal {
19+
let stringValue = try decode(String.self, forKey: key)
20+
guard let decimalValue = numberFormatter.number(from: stringValue)?.decimalValue else {
21+
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Expected string to be convertible to Decimal")
22+
}
23+
return decimalValue
24+
}
25+
26+
func decodeUSFloat(forKey key: K) throws -> Float {
27+
let stringValue = try decode(String.self, forKey: key)
28+
guard let floatValue = numberFormatter.number(from: stringValue)?.floatValue else {
29+
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Expected string to be convertible to Float")
30+
}
31+
return floatValue
32+
}
33+
34+
func decodeUSInt(forKey key: K) throws -> Int {
35+
let stringValue = try decode(String.self, forKey: key)
36+
guard let intValue = numberFormatter.number(from: stringValue)?.intValue else {
37+
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Expected string to be convertible to Int")
38+
}
39+
return intValue
40+
}
41+
}

Sources/AlphaSwiftage/Public/Model/CurrencyExchangeRate.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ public struct CurrencyExchangeRate: Codable, Equatable {
4141
fromCurrencyName = try container.decode(String.self, forKey: .fromCurrencyName)
4242
toCurrencyCode = try container.decode(String.self, forKey: .toCurrencyCode)
4343
toCurrencyName = try container.decode(String.self, forKey: .toCurrencyName)
44-
exchangeRate = try container.decodeDecimal(forKey: .exchangeRate)
45-
bidPrice = try container.decodeDecimal(forKey: .bidPrice)
46-
askPrice = try container.decodeDecimal(forKey: .askPrice)
44+
exchangeRate = try container.decodeUSDecimal(forKey: .exchangeRate)
45+
bidPrice = try container.decodeUSDecimal(forKey: .bidPrice)
46+
askPrice = try container.decodeUSDecimal(forKey: .askPrice)
4747

4848

4949
// Handling TimeZone

Sources/AlphaSwiftage/Public/Model/Quote.swift

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ public struct Quote: Codable, Equatable {
4141
public init(from decoder: Decoder) throws {
4242
let container = try decoder.container(keyedBy: CodingKeys.self)
4343
symbol = try container.decode(String.self, forKey: .symbol)
44-
open = try container.decodeDecimal(forKey: .open)
45-
high = try container.decodeDecimal(forKey: .high)
46-
low = try container.decodeDecimal(forKey: .low)
47-
price = try container.decodeDecimal(forKey: .price)
48-
volume = try container.decodeInt(forKey: .volume)
49-
previousClose = try container.decodeDecimal(forKey: .previousClose)
50-
change = try container.decodeDecimal(forKey: .change)
44+
open = try container.decodeUSDecimal(forKey: .open)
45+
high = try container.decodeUSDecimal(forKey: .high)
46+
low = try container.decodeUSDecimal(forKey: .low)
47+
price = try container.decodeUSDecimal(forKey: .price)
48+
volume = try container.decodeUSInt(forKey: .volume)
49+
previousClose = try container.decodeUSDecimal(forKey: .previousClose)
50+
change = try container.decodeUSDecimal(forKey: .change)
5151
changePercent = try container.decode(String.self, forKey: .changePercent)
5252

5353
let dateString = try container.decode(String.self, forKey: .latestTradingDay)
@@ -60,21 +60,3 @@ public struct Quote: Codable, Equatable {
6060
latestTradingDay = date
6161
}
6262
}
63-
64-
extension KeyedDecodingContainer {
65-
func decodeDecimal(forKey key: K) throws -> Decimal {
66-
let stringValue = try decode(String.self, forKey: key)
67-
guard let decimalValue = Decimal(string: stringValue) else {
68-
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Expected string to be convertible to Decimal")
69-
}
70-
return decimalValue
71-
}
72-
73-
func decodeInt(forKey key: K) throws -> Int {
74-
let stringValue = try decode(String.self, forKey: key)
75-
guard let decimalValue = Int(stringValue) else {
76-
throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "Expected string to be convertible to Int")
77-
}
78-
return decimalValue
79-
}
80-
}

Sources/AlphaSwiftage/Public/Model/Symbol.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ public struct Symbol: Codable, Equatable {
3939
marketOpen = try container.decode(String.self, forKey: .marketOpen)
4040
marketClose = try container.decode(String.self, forKey: .marketClose)
4141
currency = try container.decode(String.self, forKey: .currency)
42-
let rawMatchScore = try container.decode(String.self, forKey: .matchScore)
43-
guard let matchScore = Float(rawMatchScore) else {
44-
throw DecodingError.dataCorruptedError(forKey: .matchScore, in: container, debugDescription: "Match score string is not a valid float.")
45-
}
46-
self.matchScore = matchScore
42+
self.matchScore = try container.decodeUSFloat(forKey: .matchScore)
4743

4844
// Handling TimeZone
4945
let timeZoneString = try container.decode(String.self, forKey: .timeZone)

0 commit comments

Comments
 (0)