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