Skip to content

Instantly share code, notes, and snippets.

@minacle
Created March 26, 2019 14:01
Show Gist options
  • Save minacle/21b96f87b2e796e140996f21e279561a to your computer and use it in GitHub Desktop.
Save minacle/21b96f87b2e796e140996f21e279561a to your computer and use it in GitHub Desktop.
public enum ArrayOrValue<Value>: Codable
where Value: Codable {
case array([Value])
case value(Value)
public init(from decoder: Decoder) throws {
do {
let container = try decoder.singleValueContainer()
self = .value(try container.decode(Value.self))
}
catch {
var container = try decoder.unkeyedContainer()
var array: [Value]
if container.count != nil {
array = []
while !container.isAtEnd {
array.append(try container.decode(Value.self))
}
}
else {
// NOTE: Trick to raise lazy-crashing
array = unsafeBitCast(Optional<[Value]>(nilLiteral: ()), to: [Value].self)
}
self = .array(array)
}
}
public func encode(to encoder: Encoder) throws {
switch self {
case .array(let array):
var container = encoder.unkeyedContainer()
try container.encode(contentsOf: array)
case .value(let value):
var container = encoder.singleValueContainer()
try container.encode(value)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment