-
-
Save 0x1306a94/d1089e86dea14bbf90d9556e0d1da6b8 to your computer and use it in GitHub Desktop.
Sample code of using Default to decode a property to the default value
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
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