Skip to content

Instantly share code, notes, and snippets.

@floriankugler
Forked from chriseidhof/libyaml.swift
Last active March 20, 2019 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save floriankugler/cfcb887b1fd10775abed to your computer and use it in GitHub Desktop.
Save floriankugler/cfcb887b1fd10775abed to your computer and use it in GitHub Desktop.
// gem install cocoapods-playgrounds
// pod playgrounds LibYAML
// Paste in the following:
import LibYAML
struct YAMLError: ErrorType {
let problem: String
let problemOffset: Int
}
indirect enum YAMLNode {
case Scalar(s: String)
case Mapping([(String,YAMLNode)])
case Sequence([YAMLNode])
}
private class YAMLDocument {
private var document: UnsafeMutablePointer<yaml_document_t> = .alloc(1)
private var nodes: [yaml_node_t] {
let nodes = document.memory.nodes
return Array(UnsafeBufferPointer(start: nodes.start, count: nodes.top - nodes.start))
}
var rootNode: YAMLNode {
return YAMLNode(nodes: nodes, node: yaml_document_get_root_node(document).memory)
}
init(string: String) throws {
var parser: UnsafeMutablePointer<yaml_parser_t> = UnsafeMutablePointer.alloc(1)
defer { parser.dealloc(1) }
yaml_parser_initialize(parser)
defer { yaml_parser_delete(parser) }
let rawData = string.dataUsingEncoding(NSUTF8StringEncoding)!
var buffer: [UInt8] = Array(count: rawData.length, repeatedValue: 0)
rawData.getBytes(&buffer, length: rawData.length)
yaml_parser_set_encoding(parser, YAML_UTF8_ENCODING)
yaml_parser_set_input_string(parser, &buffer, buffer.count)
guard yaml_parser_load(parser, document) == 1 else {
throw YAMLError(problem: String.fromCString(parser.memory.problem)!, problemOffset: parser.memory.problem_offset)
}
}
deinit {
yaml_document_delete(document)
document.dealloc(1)
}
}
extension YAMLNode {
private init(nodes: [yaml_node_s], node: yaml_node_s) {
switch node.type {
case YAML_MAPPING_NODE:
let pairs = node.data.mapping.pairs
self = .Mapping(UnsafeBufferPointer(start: pairs.start, count: pairs.top - pairs.start).map { pair in
let key = YAMLNode(nodes: nodes, node: nodes[pair.key - 1])
guard case let .Scalar(value) = key else { fatalError("Not a scalar key") }
return (value, YAMLNode(nodes: nodes, node: nodes[pair.value - 1]))
})
case YAML_SEQUENCE_NODE:
let items = node.data.sequence.items
self = .Sequence(UnsafeBufferPointer(start: items.start, count: items.top - items.start).map { item in
return YAMLNode(nodes: nodes, node: nodes[item - 1])
})
case YAML_SCALAR_NODE:
self = .Scalar(s: String.fromCString(UnsafeMutablePointer(node.data.scalar.value))!)
default:
fatalError("TODO")
}
}
init(string: String) throws {
self = try YAMLDocument(string: string).rootNode
}
}
let node = try YAMLNode(string: "- 1: test the world\n two: { hello: world }")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment