Skip to content

Instantly share code, notes, and snippets.

@onevcat
Created November 10, 2020 03:56
Show Gist options
  • Select an option

  • Save onevcat/0f055ece50bd0c07e882890129dfcfb8 to your computer and use it in GitHub Desktop.

Select an option

Save onevcat/0f055ece50bd0c07e882890129dfcfb8 to your computer and use it in GitHub Desktop.
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)
@skywalkerlw
Copy link
Copy Markdown

can we support default Empty Array and Dictionary?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment