Skip to content

Instantly share code, notes, and snippets.

@pixyzehn
Forked from chriseidhof/libyaml.swift
Created December 4, 2016 00:57
Show Gist options
  • Save pixyzehn/e0eb21038cfff913969e26076e3b4d9a to your computer and use it in GitHub Desktop.
Save pixyzehn/e0eb21038cfff913969e26076e3b4d9a to your computer and use it in GitHub Desktop.
// gem install cocoapods-playgrounds
// pod playgrounds LibYAML
// Update: @floriankugler had a great idea to use UnsafeBufferPointer
// Paste in the following:
import LibYAML
public struct YAMLError: ErrorType {
let problem: String
let problemOffset: Int
}
public 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> = .alloc(1)
defer { parser.dealloc(1) }
yaml_parser_initialize(parser)
defer { yaml_parser_delete(parser) }
var bytes = string.utf8.map { UInt8($0) }
yaml_parser_set_encoding(parser, YAML_UTF8_ENCODING)
yaml_parser_set_input_string(parser, &bytes, bytes.count-1)
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) {
let newNode: Int32 -> YAMLNode = { x in YAMLNode(nodes: nodes, node: nodes[x-1]) }
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
guard case let .Scalar(value) = newNode(pair.key) else { fatalError("Not a scalar key") }
return (value, newNode(pair.value))
})
case YAML_SEQUENCE_NODE:
let items = node.data.sequence.items
self = .Sequence(UnsafeBufferPointer(start: items.start, count: items.top - items.start).map(newNode))
case YAML_SCALAR_NODE:
self = .Scalar(s: String.fromCString(UnsafeMutablePointer(node.data.scalar.value))!)
default:
fatalError("TODO")
}
}
public init(string: String) throws {
self = try YAMLDocument(string: string).rootNode
}
}
let node = try YAMLNode(string: "- 1: test ")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment