Created
October 3, 2024 18:36
-
-
Save IanKeen/46f3f8d8d8605730d74e2177e26b0e28 to your computer and use it in GitHub Desktop.
PropertyWrapper: AllowDecodingFailure will catch decoding errors and return `nil` rather than failing the operation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Dingus: Codable { | |
@AllowDecodingFailure var foo: String? | |
} | |
do { | |
let model = try JSONDecoder().decode(Dingus.self, from: Data("{\"foo\": 123}".utf8)) | |
model.foo // nil | |
} | |
do { | |
let model = try JSONDecoder().decode(Dingus.self, from: Data("{\"foo\": \"hello\"}".utf8)) | |
model.foo // hello | |
} | |
do { | |
let model = try JSONDecoder().decode(Dingus.self, from: Data("{}".utf8)) // throws | |
model.foo | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@propertyWrapper | |
public struct AllowDecodingFailure<T: Codable>: Codable { | |
public var wrappedValue: T? | |
public var error: Error? | |
public var projectedValue: AllowDecodingFailure<T> { self } | |
public init(wrappedValue: T?) { | |
self.wrappedValue = wrappedValue | |
self.error = nil | |
} | |
public init(from decoder: Decoder) throws { | |
do { | |
self.wrappedValue = try T(from: decoder) | |
} catch let error { | |
self.error = error | |
} | |
} | |
public func encode(to encoder: Encoder) throws { | |
try wrappedValue.encode(to: encoder) | |
} | |
} | |
extension KeyedDecodingContainer { | |
public func decode<T>(_ type: AllowDecodingFailure<T>.Type, forKey key: KeyedDecodingContainer.Key) throws -> AllowDecodingFailure<T> { | |
return AllowDecodingFailure(wrappedValue: try? decode(T.self, forKey: key)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment