Na(t)ive YAML/JSON (de)serializer for Swift
Na(t)ive YAML/JSON (de)serializer for Swift. It started with a naive question “how hard it can be to write YAML parser?”, followed by a naive answer “it can’t be that hard”. 😉 It’s not a complete YAML 1.[012] implementation yet, but it proved to be usable for reading and writing basic YAML/JSON structures at decent speed.
Parse YAML or JSON and access data directly:
import UniYAML
let json = """
{
\"first name\": Antonio,
\"middle name\": Lucio,
surname: Vivaldi,
nickname: 'il Prete Rosso',
born: 1678
}
"""
do {
let obj = try UniYAML.decode(json)
print("person details available: \(obj.keys)")
print("\(obj["first name"]?.string) \(obj["surname"]?.string) aka \(obj["nickname"]?.string) was born on \(obj["born"]?.uint)")
} catch UniYAMLError.error(let detail) {
print(detail)
}
import UniYAML
let yaml = """
---
classic:
-
author: Ludwig van Beethoven
title: Für Elise
published: 1867
duration: 3:30
-
author: Wolfgang Amdeus Mozart
title: Eine kleine Nachtmusik
published: 1787
duration: 5:45
-
author: Bedřich Smetana
title: Vltava
published: 1874
duration: 12:50
"""
do {
let obj = try UniYAML.decode(yaml)
let collection = obj["classic"]!.array!
print("there are \(collection.count) entries in 'classic' collection")
let first = collection[0].dictionary!
let last = collection.last!.dictionary!
print("shortest (\(first["duration"]?.string)) is \(first["title"]?.string) from \(first["author"]?.string)")
print("longest (\(last["duration"]?.string)) is \(last["title"]?.string) from \(last["author"]?.string)")
} catch UniYAMLError.error(let detail) {
print(detail)
}
Easily convert parsed content to expected types:
import UniYAML
let types = """
---
no choice: don't say anything
variants: 'say ''yes'' or ''no'''
split string: >
two
words
rows: |
first
second
last
int: -12345
uint: 67890
double: 3.14159265
positive: yes
negative: off
"""
do {
let obj = try UniYAML.decode(types)
print("string: '\(obj["variants"]?.string)'")
print("multi-line string: '\(obj["rows"]?.string)'")
print("integer: \(obj["int"]?.int)")
print("unsigned integer: \(obj["uint"]?.uint)")
print("double: \(obj["double"]?.double)")
print("bool: \(obj["negative"]?.bool)")
} catch UniYAMLError.error(let detail) {
print(detail)
}
Serialize custom data structures:
import UniYAML
do {
let obj1 = YAML([1, 2, "A", "B"])!
let json = try UniYAML.encode(obj1)
let obj2 = YAML(["key": "value", "int": -987, "double": -543.21])!
let yaml = try UniYAML.encode(obj2, with: .yaml)
let obj3 = YAML(["key": "value", "array": YAML([10, 11, 12])!, "dict": YAML(["number": 1, "text": "test", "double": 12.34])!])!
let complex = try UniYAML.encode(obj3)
} catch UniYAMLError.error(let detail) {
print(detail)
}
Written by Daniel Fojt, copyright Seznam.cz, licensed under the terms of the Apache License 2.0.