Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import Foundation
public protocol EmptyInitializable {
init()
}
extension Int: EmptyInitializable {}
extension String: EmptyInitializable {}
extension Array: EmptyInitializable {}
extension Bool: EmptyInitializable {}
@propertyWrapper
public struct EmptyDecoded<T: Decodable & EmptyInitializable>: Decodable {
public var wrappedValue: T
public init(wrappedValue: T) {
self.wrappedValue = wrappedValue
}
public init(from decoder: Decoder) throws {
guard let container = try? decoder.singleValueContainer(),
let value = try? container.decode(T.self) else {
wrappedValue = T()
return
}
wrappedValue = value
}
}
extension EmptyDecoded: Equatable where T: Equatable {}
extension EmptyDecoded: Hashable where T: Hashable {}
extension KeyedDecodingContainer {
public func decode<T>(_ type: EmptyDecoded<T>.Type, forKey key: K) throws -> EmptyDecoded<T> where T: Decodable & EmptyInitializable {
try EmptyDecoded<T>(from: superDecoder(forKey: key))
}
}
struct Spot: Decodable {
var id: Int
var name: String
@EmptyDecoded
var isGoodPlace: Bool
}
let string = #"{ "id": 300, "name": "AppBrew"}"#
print(try! JSONDecoder().decode(Spot.self, from: string.data(using: .utf8)!))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment