115 lines
2.1 KiB
Swift
115 lines
2.1 KiB
Swift
import Foundation
|
|
@preconcurrency import Parsing
|
|
|
|
var yamlString = """
|
|
---
|
|
author: Michael Housh
|
|
categories:
|
|
- HVAC
|
|
- General
|
|
- Programming
|
|
copy: true
|
|
draft: false
|
|
date: 2023-10-21
|
|
lastmod: 2023-10-21
|
|
image: banner.png
|
|
featuredImage: banner.png
|
|
tags:
|
|
- HVAC
|
|
- General
|
|
- Programming
|
|
title: "You Should Learn Markdown"
|
|
"""[...].utf8
|
|
|
|
struct YamlString: Parser {
|
|
|
|
var body: some Parser<Substring.UTF8View, String> {
|
|
OneOf {
|
|
Parse {
|
|
"\"".utf8
|
|
PrefixUpTo("\"".utf8)
|
|
"\"".utf8
|
|
}.map(.string)
|
|
|
|
Prefix { $0 != UInt8(ascii: "\n") }.map(.string)
|
|
}
|
|
}
|
|
}
|
|
|
|
struct YamlObject: Parser {
|
|
|
|
enum Value {
|
|
case array([String])
|
|
case boolean(Bool)
|
|
case date(YamlDate.Output)
|
|
case string(String)
|
|
}
|
|
|
|
var body: some Parser<Substring.UTF8View, [String: Value]> {
|
|
"---".utf8
|
|
Many(into: [String: Value]()) { (dict: inout [String: Value], pair: (String, Value)) in
|
|
dict[pair.0] = pair.1
|
|
} element: {
|
|
PrefixUpTo(":".utf8).map(.string)
|
|
":".utf8
|
|
OneOf {
|
|
Parse {
|
|
"\n".utf8
|
|
YamlArray()
|
|
}.map { Value.array($0) }
|
|
|
|
Parse {
|
|
Whitespace()
|
|
Bool.parser().map { Value.boolean($0) }
|
|
}
|
|
|
|
Parse {
|
|
Whitespace()
|
|
YamlDate().map { Value.date($0) }
|
|
}
|
|
|
|
Parse {
|
|
Whitespace()
|
|
YamlString().map { Value.string($0) }
|
|
}
|
|
}
|
|
} separator: {
|
|
"\n".utf8
|
|
}
|
|
}
|
|
}
|
|
|
|
struct YamlArray: Parser {
|
|
var body: some Parser<Substring.UTF8View, [String]> {
|
|
Many(into: [String]()) { array, string in
|
|
array.append(string)
|
|
} element: {
|
|
Whitespace(.horizontal)
|
|
"- ".utf8
|
|
Prefix { $0 != UInt8(ascii: "\n") }.map(.string)
|
|
} separator: {
|
|
"\n".utf8
|
|
}
|
|
}
|
|
}
|
|
|
|
struct YamlDate: Parser {
|
|
struct Output {
|
|
let year: Int
|
|
let month: Int
|
|
let day: Int
|
|
}
|
|
|
|
var body: some Parser<Substring.UTF8View, Output> {
|
|
Parse(.memberwise(Output.init)) {
|
|
Digits(4)
|
|
"-".utf8
|
|
Digits(2)
|
|
"-".utf8
|
|
Digits(2)
|
|
}
|
|
}
|
|
}
|
|
|
|
try print(YamlObject().parse(&yamlString))
|