@@ -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