Skip to content

Instantly share code, notes, and snippets.

@davbeck
Created May 2, 2015 15:52
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save davbeck/e96b543bc0184b04353e to your computer and use it in GitHub Desktop.
Save davbeck/e96b543bc0184b04353e to your computer and use it in GitHub Desktop.
GraphQL data structure implemented in Swift
import Foundation
protocol GQLNodeArgument {}
extension String: GQLNodeArgument {}
extension NSNumber: GQLNodeArgument {}
class GQLNode: StringLiteralConvertible, ArrayLiteralConvertible, Printable, DebugPrintable {
let name: String?
let arguments: [String : GQLNodeArgument]
let properties: [GQLNode]
var isRootNode: Bool {
return self.name?.isEmpty ?? true
}
init(name: String, arguments: [String : GQLNodeArgument] = [:], properties: [GQLNode] = []) {
for node in properties {
assert(!node.isRootNode, "You cannot include a root node, or a node with an empty name as a child of another node.")
}
self.name = name
self.arguments = arguments
self.properties = properties
}
required convenience init(stringLiteral value: StringLiteralType) {
self.init(name: value)
}
required convenience init(extendedGraphemeClusterLiteral value: StringLiteralType) {
self.init(name: value)
}
required convenience init(unicodeScalarLiteral value: StringLiteralType) {
self.init(name: value)
}
required convenience init(arrayLiteral elements: GQLNode...) {
self.init(name: "", properties: elements)
}
func render(pretty: Bool = false, indentationLevel: Int = 0) -> String {
var rendered: String = ""
let indentationText: String
if pretty {
indentationText = "".join(Array(count: indentationLevel, repeatedValue: " "))
} else {
indentationText = ""
}
rendered += indentationText
if let name = self.name {
rendered += name
}
if self.arguments.count > 0 {
rendered += "("
var argumentTexts: [String] = []
for (name, argument) in self.arguments {
argumentTexts.append("\(name): \(argument)")
}
rendered += ", ".join(argumentTexts)
if pretty {
rendered += ") "
} else {
rendered += ")"
}
}
if self.properties.count > 0 {
rendered += "{"
if pretty {
rendered += "\n"
}
var propertyTexts: [String] = []
for property in self.properties {
propertyTexts.append(property.render(pretty: pretty, indentationLevel: indentationLevel + 1))
}
if pretty {
rendered += ",\n".join(propertyTexts)
} else {
rendered += ",".join(propertyTexts)
}
if pretty {
rendered += "\n"
}
rendered += indentationText + "}"
}
return rendered
}
var description: String {
return self.render(pretty: true)
}
var debugDescription: String {
return "GQLNode(\(self.render(pretty: true)))"
}
}
let query: GQLNode = [
GQLNode(name: "user", arguments: ["id" : 3500401], properties: [
"id",
"name",
"isViewerFriend",
GQLNode(name: "profilePicture", arguments: ["size" : 50], properties: [
"uri",
"width",
"height",
]),
])
]
query.render(pretty: true)
query.render(pretty: false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment