Files
2022-07-30 20:47:39 +02:00

91 lines
3.2 KiB
Swift

//
// SwiftGenKit
// Copyright © 2022 SwiftGen
// MIT Licence
//
import Foundation
import Kanna
extension CoreData {
public struct Entity {
public let name: String
public let className: String
public let isAbstract: Bool
public let userInfo: [String: Any]
public let superEntity: String?
public let attributes: [Attribute]
public let relationships: [Relationship]
public let fetchedProperties: [FetchedProperty]
public let uniquenessConstraints: [[String]]
public let shouldGenerateCode: Bool
}
}
private enum XML {
fileprivate enum Attributes {
static let name = "name"
static let representedClassName = "representedClassName"
static let isAbstract = "isAbstract"
static let superEntity = "parentEntity"
static let codeGenerationType = "codeGenerationType"
}
fileprivate enum Values {
static let categoryCodeGeneration = "category"
static let classCodeGeneration = "class"
}
static let attributesPath = "attribute"
static let relationshipsPath = "relationship"
static let fetchedPropertiesPath = "fetchedProperty"
static let userInfoPath = "userInfo"
static let uniquenessConstraintsPath = "uniquenessConstraints"
}
extension CoreData.Entity {
init(with object: Kanna.XMLElement) throws {
guard let name = object[XML.Attributes.name] else {
throw CoreData.ParserError.invalidFormat(reason: "Missing required entity name.")
}
// The module and the class name are stored in the same field, separated by a '.'. If the user chooses
// "current product module", the field is prefixed with a '.'. We actually do not want the module part of the type,
// so we need to remove it.
let classComponents = (object[XML.Attributes.representedClassName] ?? "").components(separatedBy: ".")
let className: String
if classComponents.count > 1 {
className = classComponents.dropFirst().joined(separator: ".")
} else {
className = classComponents.joined(separator: ".")
}
let isAbstract = object[XML.Attributes.isAbstract].flatMap(Bool.init(from:)) ?? false
let superEntity = object[XML.Attributes.superEntity]
let shouldGenerateCode = object[XML.Attributes.codeGenerationType].map { value in
value != XML.Values.categoryCodeGeneration && value != XML.Values.classCodeGeneration
} ?? true
let attributes = try object.xpath(XML.attributesPath).map(CoreData.Attribute.init(with:))
let relationships = try object.xpath(XML.relationshipsPath).map(CoreData.Relationship.init(with:))
let fetchedProperties = try object.xpath(XML.fetchedPropertiesPath).map(CoreData.FetchedProperty.init(with:))
let userInfo = try object.at_xpath(XML.userInfoPath).map { try CoreData.UserInfo.parse(from: $0) } ?? [:]
let uniquenessConstraints = try object.at_xpath(XML.uniquenessConstraintsPath).map { element in
try CoreData.UniquenessConstraints.parse(from: element)
} ?? []
self.init(
name: name,
className: className,
isAbstract: isAbstract,
userInfo: userInfo,
superEntity: superEntity,
attributes: attributes,
relationships: relationships,
fetchedProperties: fetchedProperties,
uniquenessConstraints: uniquenessConstraints,
shouldGenerateCode: shouldGenerateCode
)
}
}