Merge branch 'feature/modelmapping' into 'feature/coding'
Feature/modelmapping See merge request BPHV_MIPS/mvm_core!45
This commit is contained in:
commit
347fd9557d
@ -9,6 +9,22 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol Model: Codable {
|
public protocol Model: Codable {
|
||||||
static var identifier: String { get set }
|
|
||||||
|
static var identifier: String { get }
|
||||||
|
|
||||||
|
static func mvmdecode<K:CodingKey>(keyedContainer: KeyedDecodingContainer<K>, codingKey: K) throws -> Self?
|
||||||
|
static func mvmdecode(unkeyedContainer: inout UnkeyedDecodingContainer) throws -> Self?
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Model {
|
||||||
|
static public func mvmdecode<K:CodingKey>(keyedContainer: KeyedDecodingContainer<K>, codingKey: K) throws -> Self? {
|
||||||
|
let m = try keyedContainer.decodeIfPresent(self, forKey: codingKey)
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
static public func mvmdecode(unkeyedContainer: inout UnkeyedDecodingContainer) throws -> Self? {
|
||||||
|
let m = try unkeyedContainer.decodeIfPresent(self)
|
||||||
|
return m
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,6 @@ public struct ModelRegistry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension KeyedDecodingContainer where Key: CodingKey {
|
extension KeyedDecodingContainer where Key: CodingKey {
|
||||||
|
|
||||||
//MARK: - Decode
|
//MARK: - Decode
|
||||||
@ -44,7 +43,7 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
public func decodeIfPresent<T, C:CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: C) throws -> T? {
|
public func decodeIfPresent<T, C:CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: C) throws -> T? {
|
||||||
|
|
||||||
//get the type string
|
//get the type string
|
||||||
let meta = try self.nestedContainer(keyedBy: type(of: typeCodingKey), forKey: codingKey)
|
let meta = try self.nestedContainer(keyedBy: C.self, forKey: codingKey)
|
||||||
guard let type = try meta.decodeIfPresent(String.self, forKey: typeCodingKey) else {
|
guard let type = try meta.decodeIfPresent(String.self, forKey: typeCodingKey) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -54,17 +53,46 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
}
|
}
|
||||||
|
|
||||||
//get the decoder for the propertyKey
|
|
||||||
let decoder = try self.superDecoder(forKey: codingKey)
|
|
||||||
|
|
||||||
//decode the type using the decoder
|
//decode the type using the decoder
|
||||||
let model = try found.init(from: decoder)
|
let model = try found.mvmdecode(keyedContainer: self, codingKey: codingKey)
|
||||||
|
|
||||||
guard let m = model as? T else {
|
guard let m = model as? T else {
|
||||||
throw ModelRegistry.Error.decoderError
|
throw ModelRegistry.Error.decoderError
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public func decodeArrayIfPresent<C:CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: C) throws -> [Model]? {
|
||||||
|
|
||||||
|
var unkeyedContainer = try nestedUnkeyedContainer(forKey: codingKey)
|
||||||
|
var otherUnkeyedContainer = try nestedUnkeyedContainer(forKey: codingKey)
|
||||||
|
var attributes = [Model.Type]()
|
||||||
|
while !unkeyedContainer.isAtEnd {
|
||||||
|
|
||||||
|
let meta = try unkeyedContainer.nestedContainer(keyedBy: C.self)
|
||||||
|
guard let type = try meta.decodeIfPresent(String.self, forKey: typeCodingKey) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
//get the type
|
||||||
|
guard let found = ModelRegistry.types[type] else {
|
||||||
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
|
}
|
||||||
|
attributes.append(found)
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
var models = [Model]()
|
||||||
|
while !otherUnkeyedContainer.isAtEnd {
|
||||||
|
let foundModel = attributes[i]
|
||||||
|
if let model = try foundModel.mvmdecode(unkeyedContainer: &otherUnkeyedContainer) {
|
||||||
|
models.append(model)
|
||||||
|
}
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
return models.count > 0 ? models : nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user