<commit_before>import Foundation

// MARK: Schema Types

extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
  
  public var queryArgumentLiteral: String {
    let argKeys = Array(self.keys)
    
    var argumentString = ""
    for item in argKeys {
      argumentString += "\(item):\(self[item]!)"
      if argKeys.last != item {
        argumentString += ","
      }
    }
    
    return argumentString
  }
  
}

public enum GQLSchemaType {
  case Query, Mutation
}

public struct GQLQuery {
  
  public init(withSchemaType schemaType: GQLSchemaType, withQueryTitle title: String, withQueryArguments arguments: [String: AnyObject]? = nil, withQuery query: GQLQueryItemType) {
    self.schemaType = schemaType
    self.queryTitle = title
    self.arguments = arguments
    self.query = query
  }
  
  public let schemaType: GQLSchemaType
  public let queryTitle: String
  public let arguments: [String: AnyObject]?
  public let query: GQLQueryItemType
  
  public var queryString: String {
    
    let argumentString: String
    if let args = self.arguments {
      argumentString = "(\(args.queryArgumentLiteral))"
    } else { argumentString = "" }
    
    let fullQuery = "{\(self.queryTitle)\(argumentString){\(self.query.queryRepresentation)}}"
    
    switch self.schemaType {
    case .Query:
      return fullQuery
    case .Mutation:
      return "mutation\(fullQuery)"
    }
  }
}

// MARK: Query Item Types / Extensions

public protocol GQLQueryItemType {
  var keyDesignation: String { get }
  var queryRepresentation: String { get }
}

extension String: GQLQueryItemType {
  public var keyDesignation: String {
    return self
  }
  
  public var queryRepresentation: String {
    return self
  }
}

public struct GQLQueryItem: GQLQueryItemType {
  
  public init(_ keyDesignation: String) {
    self.init(withKeyDesignation: keyDesignation, andSubqueryFields: nil)
  }
  
  public init(withKeyDesignation keyDesignation: String, andSubqueryFields fields: [GQLQueryItemType]?) {
    self.keyDesignation = keyDesignation
    self.fields = fields
  }
  
  public let keyDesignation: String
  public let fields: [GQLQueryItemType]? 
  
  public var queryRepresentation: String {
    if let fields = self.fields {
      let subqueryString = fields.map { return $0.queryRepresentation }.joinWithSeparator(",")
      return "\(self.keyDesignation){\(subqueryString)}"
    } else {
      return "\(self.keyDesignation)"
    }
  }
  <commit_msg>fixed a design issue where you couldn't add multiple top-level query items to a query<commit_after>import Foundation

// MARK: Schema Types

extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
  
  public var queryArgumentLiteral: String {
    let argKeys = Array(self.keys)
    
    var argumentString = ""
    for item in argKeys {
      argumentString += "\(item):\(self[item]!)"
      if argKeys.last != item {
        argumentString += ","
      }
    }
    
    return argumentString
  }
  
}

public enum GQLSchemaType {
  case Query, Mutation
}

public struct GQLQuery {
  
  public init(withSchemaType schemaType: GQLSchemaType, withQueryTitle title: String, withQueryArguments arguments: [String: AnyObject]? = nil, withQueryItems queryItems: [GQLQueryItemType]) {
    self.schemaType = schemaType
    self.queryTitle = title
    self.arguments = arguments
    self.queryItems = queryItems
  }
  
  public let schemaType: GQLSchemaType
  public let queryTitle: String
  public let arguments: [String: AnyObject]?
  public let queryItems: [GQLQueryItemType]
  
  public var queryString: String {
    
    let argumentString: String
    if let args = self.arguments {
      argumentString = "(\(args.queryArgumentLiteral))"
    } else { argumentString = "" }
    
    let fullQuery = "{\(self.queryTitle)\(argumentString){\(self.queryItems.map { return $0.queryRepresentation }.joinWithSeparator(","))}}"
    
    switch self.schemaType {
    case .Query:
      return "query=\(fullQuery)"
    case .Mutation:
      return "query=mutation\(fullQuery)"
    }
  }
}

// MARK: Query Item Types / Extensions

public protocol GQLQueryItemType {
  var keyDesignation: String { get }
  var queryRepresentation: String { get }
}

extension String: GQLQueryItemType {
  public var keyDesignation: String {
    return self
  }
  
  public var queryRepresentation: String {
    return self
  }
}

public struct GQLQueryItem: GQLQueryItemType {
  
  public init(_ keyDesignation: String) {
    self.init(withKeyDesignation: keyDesignation, andSubqueryFields: nil)
  }
  
  public init(withKeyDesignation keyDesignation: String, andSubqueryFields fields: [GQLQueryItemType]?) {
    self.keyDesignation = keyDesignation
    self.fields = fields
  }
  
  public let keyDesignation: String
  public let fields: [GQLQueryItemType]?
  
  public var queryRepresentation: String {
    if let fields = self.fields {
      let subqueryString = fields.map { return $0.queryRepresentation }.joinWithSeparator(",")
      return "\(self.keyDesignation){\(subqueryString)}"
    } else {
      return "\(self.keyDesignation)"
    }
  }
  
{'fraction_non_alphanumeric': 0.09349990240093695, 'fraction_numerical': 0.0005855943782939684, 'mean_word_length': 3.357142857142857, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '501156', 'n_tokens_mistral': 1513, 'n_tokens_neox': 1508, 'n_words': 399}