Created
June 28, 2017 14:42
-
-
Save sjoerdvisscher/255a0ea58706f63ed84958b6f3c46b82 to your computer and use it in GitHub Desktop.
Using Decodable to generate a minimal value
This file contains hidden or 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 MinimalDecoder : Decoder { | |
var codingPath = [CodingKey?]() | |
var userInfo = [CodingUserInfoKey : Any]() | |
public func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> { | |
return KeyedDecodingContainer(MinimalKeyedDecodingContainer<Key>(decoder: self)) | |
} | |
public func unkeyedContainer() throws -> UnkeyedDecodingContainer { | |
return DecodingContainer(decoder: self) | |
} | |
public func singleValueContainer() throws -> SingleValueDecodingContainer { | |
return DecodingContainer(decoder: self) | |
} | |
} | |
struct DecodingContainer : UnkeyedDecodingContainer, SingleValueDecodingContainer { | |
let codingPath = [CodingKey?]() | |
let count : Int? = nil | |
let isAtEnd = true | |
let decoder: MinimalDecoder | |
func decodeNil() -> Bool { | |
return true | |
} | |
func decode(_ type: String.Type) throws -> String { | |
return "" | |
} | |
func decode(_ type: Double.Type) throws -> Double { | |
return 0 | |
} | |
func decode(_ type: Float.Type) throws -> Float { | |
return 0 | |
} | |
func decode(_ type: UInt64.Type) throws -> UInt64 { | |
return 0 | |
} | |
func decode(_ type: UInt32.Type) throws -> UInt32 { | |
return 0 | |
} | |
func decode(_ type: UInt16.Type) throws -> UInt16 { | |
return 0 | |
} | |
func decode(_ type: UInt8.Type) throws -> UInt8 { | |
return 0 | |
} | |
func decode(_ type: UInt.Type) throws -> UInt { | |
return 0 | |
} | |
func decode(_ type: Int64.Type) throws -> Int64 { | |
return 0 | |
} | |
func decode(_ type: Int32.Type) throws -> Int32 { | |
return 0 | |
} | |
func decode(_ type: Int16.Type) throws -> Int16 { | |
return 0 | |
} | |
func decode(_ type: Int8.Type) throws -> Int8 { | |
return 0 | |
} | |
func decode(_ type: Int.Type) throws -> Int { | |
return 0 | |
} | |
func decode(_ type: Bool.Type) throws -> Bool { | |
return false | |
} | |
func decode<T>(_ type: T.Type) throws -> T where T : Decodable { | |
return T.minimal! | |
} | |
func decodeIfPresent<T>(_ type: T.Type) throws -> T? where T : Decodable { | |
return T.minimal | |
} | |
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<NestedKey> { | |
return KeyedDecodingContainer(MinimalKeyedDecodingContainer<NestedKey>(decoder: decoder)) | |
} | |
func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { | |
return self | |
} | |
func superDecoder() throws -> Decoder { | |
return decoder | |
} | |
} | |
struct MinimalKeyedDecodingContainer<K : CodingKey> : KeyedDecodingContainerProtocol { | |
typealias Key = K | |
let decoder : MinimalDecoder | |
let allKeys = [Key]() | |
let codingPath = [CodingKey?]() | |
func contains(_ key: K) -> Bool { | |
return true | |
} | |
func decodeIfPresent(_ type: Bool.Type, forKey key: K) throws -> Bool? { | |
return false | |
} | |
func decodeIfPresent(_ type: Int.Type, forKey key: K) throws -> Int? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: Int8.Type, forKey key: K) throws -> Int8? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: Int16.Type, forKey key: K) throws -> Int16? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: Int32.Type, forKey key: K) throws -> Int32? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: Int64.Type, forKey key: K) throws -> Int64? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: UInt.Type, forKey key: K) throws -> UInt? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: UInt8.Type, forKey key: K) throws -> UInt8? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: UInt16.Type, forKey key: K) throws -> UInt16? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: UInt32.Type, forKey key: K) throws -> UInt32? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: UInt64.Type, forKey key: K) throws -> UInt64? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: Float.Type, forKey key: K) throws -> Float? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: Double.Type, forKey key: K) throws -> Double? { | |
return 0 | |
} | |
func decodeIfPresent(_ type: String.Type, forKey key: K) throws -> String? { | |
return "" | |
} | |
func decodeIfPresent<T>(_ type: T.Type, forKey key: K) throws -> T? where T : Decodable { | |
return T.minimal | |
} | |
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: K) throws -> KeyedDecodingContainer<NestedKey> { | |
return KeyedDecodingContainer(MinimalKeyedDecodingContainer<NestedKey>(decoder: decoder)) | |
} | |
func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer { | |
return DecodingContainer(decoder: decoder) | |
} | |
func superDecoder() throws -> Decoder { | |
return decoder | |
} | |
func superDecoder(forKey key: K) throws -> Decoder { | |
return decoder | |
} | |
} | |
extension Decodable { | |
static var minimal: Self? { | |
return try? Self(from: MinimalDecoder()) | |
} | |
} | |
struct Test : Codable { | |
var int: Int | |
var bool: Bool | |
var arr: [Test] | |
var opt: String? | |
} | |
var t : Test? = Test.minimal | |
print(t.debugDescription) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment