Sample code of using Default to decode a property to the default value
import UIKit | |
protocol DefaultValue { | |
associatedtype Value: Decodable | |
static var defaultValue: Value { get } | |
} | |
@propertyWrapper | |
struct Default<T: DefaultValue> { | |
var wrappedValue: T.Value | |
} | |
extension Default: Decodable { | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
wrappedValue = (try? container.decode(T.Value.self)) ?? T.defaultValue | |
} | |
} | |
extension KeyedDecodingContainer { | |
func decode<T>( | |
_ type: Default<T>.Type, | |
forKey key: Key | |
) throws -> Default<T> where T: DefaultValue { | |
try decodeIfPresent(type, forKey: key) ?? Default(wrappedValue: T.defaultValue) | |
} | |
} | |
struct Video: Decodable { | |
enum State: String, Decodable, DefaultValue { | |
case streaming | |
case archived | |
case unknown | |
static let defaultValue = Video.State.unknown | |
} | |
let id: Int | |
let title: String | |
@Default.False var commentEnabled: Bool | |
@Default.True var publicVideo: Bool | |
@Default<State> var state: State | |
} | |
extension Bool { | |
enum False: DefaultValue { | |
static let defaultValue = false | |
} | |
enum True: DefaultValue { | |
static let defaultValue = true | |
} | |
} | |
extension Default { | |
typealias True = Default<Bool.True> | |
typealias False = Default<Bool.False> | |
} | |
let json = #"{"id": 12345, "title": "My First Video", "state": "reserved"}"# | |
let value = try! JSONDecoder().decode(Video.self, from: json.data(using: .utf8)!) | |
print(value) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment