@@ -110,230 +110,3 @@ extension DefaultCodable: Hashable where Default.DefaultValue: Hashable {
110110}
111111
112112extension DefaultCodable : Sendable where Default. DefaultValue: Sendable { }
113-
114- // MARK: - KeyedDecodingContainer
115-
116- public protocol BoolCodableStrategy : DefaultCodableStrategy where DefaultValue == Bool { }
117-
118- extension KeyedDecodingContainer {
119- /// Default implementation of decoding a DefaultCodable
120- ///
121- /// Decodes successfully if key is available if not fallback to the default value provided.
122- public func decode< P> ( _: DefaultCodable < P > . Type , forKey key: Key ) throws -> DefaultCodable < P > {
123- // Check if key exists
124- if !contains( key) {
125- #if DEBUG
126- let context = DecodingError . Context (
127- codingPath: codingPath + [ key] ,
128- debugDescription: " Key not found but property is non-optional "
129- )
130- let error = DecodingError . keyNotFound ( key, context)
131- let decoder = try ? superDecoder ( forKey: key)
132- decoder? . reportError ( error)
133- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
134- #else
135- return DefaultCodable ( wrappedValue: P . defaultValue)
136- #endif
137- }
138-
139- // Check for nil
140- if ( try ? decodeNil ( forKey: key) ) == true {
141- #if DEBUG
142- let context = DecodingError . Context (
143- codingPath: codingPath + [ key] ,
144- debugDescription: " Value was nil but property is non-optional "
145- )
146- let error = DecodingError . valueNotFound ( P . DefaultValue. self, context)
147- let decoder = try ? superDecoder ( forKey: key)
148- decoder? . reportError ( error)
149- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
150- #else
151- return DefaultCodable ( wrappedValue: P . defaultValue)
152- #endif
153- }
154-
155- // Try to decode normally
156- if let value = try decodeIfPresent ( DefaultCodable< P> . self , forKey: key) {
157- return value
158- } else {
159- #if DEBUG
160- let context = DecodingError . Context (
161- codingPath: codingPath + [ key] ,
162- debugDescription: " Key not found but property is non-optional "
163- )
164- let error = DecodingError . keyNotFound ( key, context)
165- let decoder = try ? superDecoder ( forKey: key)
166- decoder? . reportError ( error)
167- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
168- #else
169- return DefaultCodable ( wrappedValue: P . defaultValue)
170- #endif
171- }
172- }
173-
174- /// Default implementation of decoding a `DefaultCodable` where its strategy is a `BoolCodableStrategy`.
175- ///
176- /// Tries to initially Decode a `Bool` if available, otherwise tries to decode it as an `Int` or `String`
177- /// when there is a `typeMismatch` decoding error. This preserves the actual value of the `Bool` in which
178- /// the data provider might be sending the value as different types. If everything fails defaults to
179- /// the `defaultValue` provided by the strategy.
180- public func decode< P: BoolCodableStrategy > ( _: DefaultCodable < P > . Type , forKey key: Key ) throws -> DefaultCodable < P > {
181- // Check if key exists
182- if !contains( key) {
183- #if DEBUG
184- let context = DecodingError . Context (
185- codingPath: codingPath + [ key] ,
186- debugDescription: " Key not found but property is non-optional "
187- )
188- let error = DecodingError . keyNotFound ( key, context)
189- let decoder = try ? superDecoder ( forKey: key)
190- decoder? . reportError ( error)
191- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
192- #else
193- return DefaultCodable ( wrappedValue: P . defaultValue)
194- #endif
195- }
196-
197- // Check for nil first
198- if ( try ? decodeNil ( forKey: key) ) == true {
199- #if DEBUG
200- let context = DecodingError . Context (
201- codingPath: codingPath + [ key] ,
202- debugDescription: " Value was nil but property is non-optional "
203- )
204- let error = DecodingError . valueNotFound ( Bool . self, context)
205- let decoder = try ? superDecoder ( forKey: key)
206- decoder? . reportError ( error)
207- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
208- #else
209- return DefaultCodable ( wrappedValue: P . defaultValue)
210- #endif
211- }
212-
213- do {
214- let value = try decode ( Bool . self, forKey: key)
215- return DefaultCodable ( wrappedValue: value)
216- } catch {
217- guard
218- let decodingError = error as? DecodingError ,
219- case . typeMismatch = decodingError
220- else {
221- // Report error and use default
222- #if DEBUG
223- let decoder = try ? superDecoder ( forKey: key)
224- decoder? . reportError ( error)
225- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
226- #else
227- return DefaultCodable ( wrappedValue: P . defaultValue)
228- #endif
229- }
230- if
231- let intValue = try ? decodeIfPresent ( Int . self, forKey: key) ,
232- let bool = Bool ( exactly: NSNumber ( value: intValue) )
233- {
234- return DefaultCodable ( wrappedValue: bool)
235- } else if
236- let stringValue = try ? decodeIfPresent ( String . self, forKey: key) ,
237- let bool = Bool ( stringValue)
238- {
239- return DefaultCodable ( wrappedValue: bool)
240- } else {
241- // Type mismatch - report error
242- #if DEBUG
243- let decoder = try ? superDecoder ( forKey: key)
244- decoder? . reportError ( decodingError)
245- return DefaultCodable (
246- wrappedValue: P . defaultValue,
247- outcome: . recoveredFrom( decodingError, wasReported: decoder != nil )
248- )
249- #else
250- return DefaultCodable ( wrappedValue: P . defaultValue)
251- #endif
252- }
253- }
254- }
255-
256- /// Decodes a DefaultCodable where the strategy's DefaultValue is RawRepresentable
257- ///
258- /// This method provides special handling for RawRepresentable types:
259- /// - If `isFrozen` is false (default), unknown raw values result in UnknownNovelValueError and use the default value
260- /// - If `isFrozen` is true, unknown raw values result in DecodingError and use the default value
261- public func decode< P> ( _: DefaultCodable < P > . Type , forKey key: Key ) throws -> DefaultCodable < P >
262- where P. DefaultValue: RawRepresentable , P. DefaultValue. RawValue: Decodable
263- {
264- // Check if key exists
265- if !contains( key) {
266- #if DEBUG
267- let context = DecodingError . Context ( codingPath: codingPath + [ key] , debugDescription: " Key not found " )
268- let error = DecodingError . keyNotFound ( key, context)
269- let decoder = try ? superDecoder ( forKey: key)
270- decoder? . reportError ( error)
271- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
272- #else
273- return DefaultCodable ( wrappedValue: P . defaultValue)
274- #endif
275- }
276-
277- // Check for nil
278- if ( try ? decodeNil ( forKey: key) ) == true {
279- #if DEBUG
280- let context = DecodingError . Context ( codingPath: codingPath + [ key] , debugDescription: " Value was nil " )
281- let error = DecodingError . valueNotFound ( P . self, context)
282- let decoder = try ? superDecoder ( forKey: key)
283- decoder? . reportError ( error)
284- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
285- #else
286- return DefaultCodable ( wrappedValue: P . defaultValue)
287- #endif
288- }
289-
290- // Try to decode the raw value
291- do {
292- let rawValue = try decode ( P . DefaultValue. RawValue. self, forKey: key)
293-
294- // Try to create the enum from raw value
295- if let value = P . DefaultValue ( rawValue: rawValue) {
296- return DefaultCodable ( wrappedValue: value)
297- } else {
298- #if DEBUG
299- /// Unknown raw value
300- let error = Self . createUnknownRawValueError (
301- for: P . DefaultValue. self,
302- rawValue: rawValue,
303- codingPath: codingPath + [ key] ,
304- isFrozen: P . isFrozen
305- )
306-
307- let decoder = try ? superDecoder ( forKey: key)
308- decoder? . reportError ( error)
309- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
310- #else
311- return DefaultCodable ( wrappedValue: P . defaultValue)
312- #endif
313- }
314- } catch {
315- #if DEBUG
316- /// Decoding the raw value failed (e.g., type mismatch)
317- let decoder = try ? superDecoder ( forKey: key)
318- decoder? . reportError ( error)
319- return DefaultCodable ( wrappedValue: P . defaultValue, outcome: . recoveredFrom( error, wasReported: decoder != nil ) )
320- #else
321- return DefaultCodable ( wrappedValue: P . defaultValue)
322- #endif
323- }
324- }
325-
326- private static func createUnknownRawValueError< T: RawRepresentable > (
327- for type: T . Type ,
328- rawValue: T . RawValue ,
329- codingPath: [ CodingKey ] ,
330- isFrozen: Bool
331- ) -> Error {
332- guard isFrozen else { return UnknownNovelValueError ( novelValue: rawValue) }
333- let context = DecodingError . Context (
334- codingPath: codingPath,
335- debugDescription: " Cannot initialize \( type) from invalid raw value \( rawValue) "
336- )
337- return DecodingError . dataCorrupted ( context)
338- }
339- }
0 commit comments