Fix LazilyDecoding not handling top-level optionals

This commit is contained in:
Shadowfacts 2020-11-11 12:44:57 -05:00
parent 366378f267
commit 0249207dcc
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
1 changed files with 12 additions and 4 deletions

View File

@ -37,10 +37,10 @@ public struct LazilyDecoding<Enclosing, Value: Codable> {
} else {
guard let data = instance[keyPath: wrapper.keyPath] else { return wrapper.fallback }
do {
let value = try decoder.decode(Value.self, from: data)
wrapper.value = value
let value = try decoder.decode(Box<Value>.self, from: data)
wrapper.value = value.value
instance[keyPath: storageKeyPath] = wrapper
return value
return value.value
} catch {
return wrapper.fallback
}
@ -50,7 +50,7 @@ public struct LazilyDecoding<Enclosing, Value: Codable> {
var wrapper = instance[keyPath: storageKeyPath]
wrapper.value = newValue
instance[keyPath: storageKeyPath] = wrapper
let newData = try? encoder.encode(newValue)
let newData = try! encoder.encode(Box(value: newValue))
instance[keyPath: wrapper.keyPath] = newData
}
}
@ -62,3 +62,11 @@ extension LazilyDecoding {
self.init(from: keyPath, fallback: [] as! Value)
}
}
extension LazilyDecoding {
// PropertyListEncoder only allows top-level types to be dicts or arrays, which breaks encoding nil-able values.
// Wrapping everything in a Box ensures that it's always a dict.
private struct Box<T: Codable>: Codable {
let value: T
}
}