<commit_before>//
//  Relationship.swift
//  SwiftGenKit
//
//  Created by <NAME> on 7/19/18.
//  Copyright © 2018 AliSoftware. All rights reserved.
//

import Foundation

extension CoreData {
  public final class Relationship {
    typealias InverseRelationshipInformation = (name: String, entityName: String)

    public let name: String
    public let isIndexed: Bool
    public let isOptional: Bool
    public var isTransient: Bool

    public let isToMany: Bool
    public let isOrdered: Bool

    public weak internal(set) var destinationEntity: Entity?
    public weak internal(set) var inverseRelationship: Relationship?

    let destinationEntityName: String
    let inverseRelationshipInformation: InverseRelationshipInformation?

    init(
      name: String,
      isIndexed: Bool,
      isOptional: Bool,
      isTransient: Bool,
      isToMany: Bool,
      isOrdered: Bool,
      destinationEntityName: String,
      inverseRelationshipInformation: InverseRelationshipInformation?
      ) {
      self.name = name
      self.isIndexed = isIndexed
      self.isOptional = isOptional
      self.isTransient = isTransient
      self.isToMany = isToMany
      self.isOrdered = isOrdered
      self.destinationEntityName = destinationEntityName
      self.inverseRelationshipInformation = inverseRelationshipInformation
    }
  }
}

<commit_msg>Handle parsing relationships.<commit_after>//
//  Relationship.swift
//  SwiftGenKit
//
//  Created by <NAME> on 7/19/18.
//  Copyright © 2018 AliSoftware. All rights reserved.
//

import Foundation
import Kanna

extension CoreData {
  public final class Relationship {
    typealias InverseRelationshipInformation = (name: String, entityName: String)

    public let name: String
    public let isIndexed: Bool
    public let isOptional: Bool
    public var isTransient: Bool

    public let isToMany: Bool
    public let isOrdered: Bool

    public weak internal(set) var destinationEntity: Entity?
    public weak internal(set) var inverseRelationship: Relationship?

    let destinationEntityName: String
    let inverseRelationshipInformation: InverseRelationshipInformation?

    init(
      name: String,
      isIndexed: Bool,
      isOptional: Bool,
      isTransient: Bool,
      isToMany: Bool,
      isOrdered: Bool,
      destinationEntityName: String,
      inverseRelationshipInformation: InverseRelationshipInformation?
      ) {
      self.name = name
      self.isIndexed = isIndexed
      self.isOptional = isOptional
      self.isTransient = isTransient
      self.isToMany = isToMany
      self.isOrdered = isOrdered
      self.destinationEntityName = destinationEntityName
      self.inverseRelationshipInformation = inverseRelationshipInformation
    }
  }
}

private enum XML {
  static let nameAttribute = "name"
  static let isIndexedAttribute = "indexed"
  static let isOptionalAttribute = "optional"
  static let isTransientAttribute = "transient"

  static let isToManyAttribute = "toMany"
  static let isOrderedAttribute = "ordered"

  static let destinationEntityNameAttribute = "destinationEntity"
  static let inverseRelationshipNameAttribute = "inverseName"
  static let inverseRelationshipEntityNameAttribute = "inverseEntity"
}

extension CoreData.Relationship {
  convenience init(with object: Kanna.XMLElement) throws {
    let name = object[XML.nameAttribute] ?? ""
    let isIndexed = object[XML.isIndexedAttribute].flatMap(Bool.init(from:)) ?? false
    let isOptional = object[XML.isOptionalAttribute].flatMap(Bool.init(from:)) ?? false
    let isTransient = object[XML.isTransientAttribute].flatMap(Bool.init(from:)) ?? false

    let isToMany = object[XML.isToManyAttribute].flatMap(Bool.init(from:)) ?? false
    let isOrdered = object[XML.isOrderedAttribute].flatMap(Bool.init(from:)) ?? false

    guard let destinationEntityName = object[XML.destinationEntityNameAttribute] else {
      throw CoreData.ParserError.invalidFormat(reason: "Missing required destination entity name")
    }

    let inverseRelationshipName = object[XML.inverseRelationshipNameAttribute]
    let inverseRelationshipEntityName = object[XML.inverseRelationshipEntityNameAttribute]

    let inverseRelationshipInformation: InverseRelationshipInformation?
    switch (inverseRelationshipName, inverseRelationshipEntityName) {
    case (.none, .none):
      inverseRelationshipInformation = nil
    case (.none, _), (_, .none):
      throw CoreData.ParserError.invalidFormat(
        reason: "Both the name and entity name are required for inverse relationships"
      )
    case let (.some(name), .some(entityName)):
      inverseRelationshipInformation = (name: name, entityName: entityName)
    }

    self.init(
      name: name,
      isIndexed: isIndexed,
      isOptional: isOptional,
      isTransient: isTransient,
      isToMany: isToMany,
      isOrdered: isOrdered,
      destinationEntityName: destinationEntityName,
      inverseRelationshipInformation: inverseRelationshipInformation
    )
  }
}

{'fraction_non_alphanumeric': 0.0754111512234256, 'fraction_numerical': 0.0036101083032490976, 'mean_word_length': 3.722537878787879, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5321520', 'n_tokens_mistral': 1399, 'n_tokens_neox': 1327, 'n_words': 353}