Skip to content

Commit 6be7100

Browse files
authored
Merge pull request vkuttyp#2 from FoxClock/CastingSafety
Added error logic to the cast as String conversion.
2 parents 8fa7c2c + 0edf619 commit 6be7100

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

Sources/SQLClientSwift/SQLRowDecoder.swift

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,13 @@ private struct SQLRowKeyedContainer<Key: CodingKey>: KeyedDecodingContainerProto
149149
}
150150

151151
private func cast<T>(_ key: Key) throws -> T {
152+
// Validate key is in columns
152153
let value = try requireValue(for: key)
154+
155+
// Direct cast as type
153156
if let v = value as? T { return v }
157+
158+
// If type is NSNumber supported
154159
if let n = value as? NSNumber {
155160
switch T.self {
156161
case is Bool.Type: return (n.boolValue) as! T
@@ -169,14 +174,40 @@ private struct SQLRowKeyedContainer<Key: CodingKey>: KeyedDecodingContainerProto
169174
default: break
170175
}
171176
}
177+
// String → primitive conversions.
172178
if let s = value as? String {
173179
switch T.self {
174-
case is Int.Type: if let i = Int(s) { return i as! T }
175-
case is Double.Type: if let d = Double(s) { return d as! T }
176-
case is Bool.Type: return (["true","1","yes"].contains(s.lowercased())) as! T
180+
case is Int.Type:
181+
guard let i = Int(s) else {
182+
throw DecodingError.typeMismatch(T.self, .init(
183+
codingPath: codingPath + [key],
184+
debugDescription: "Cannot convert '\(s)' to Int for column '\(key.stringValue)'."))
185+
}
186+
return i as! T
187+
188+
case is Double.Type:
189+
guard let d = Double(s) else {
190+
throw DecodingError.typeMismatch(T.self, .init(
191+
codingPath: codingPath + [key],
192+
debugDescription: "Cannot convert '\(s)' to Double for column '\(key.stringValue)'."))
193+
}
194+
return d as! T
195+
196+
case is Bool.Type:
197+
switch s.lowercased() {
198+
case "true", "1", "yes": return true as! T
199+
case "false", "0", "no": return false as! T
200+
default:
201+
throw DecodingError.typeMismatch(T.self, .init(
202+
codingPath: codingPath + [key],
203+
debugDescription: "Cannot convert '\(s)' to Bool for column '\(key.stringValue)'. "
204+
+ "Expected one of: true, false, 1, 0, yes, no."))
205+
}
206+
177207
default: break
178208
}
179209
}
210+
// No Conversion path succeeded
180211
throw DecodingError.typeMismatch(T.self, .init(
181212
codingPath: codingPath + [key],
182213
debugDescription: "Expected \(T.self), got \(type(of: value)) for column '\(key.stringValue)'"))

0 commit comments

Comments
 (0)