import Foundation @preconcurrency import Parsing let 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" """ _ = """ series: - General title: "You Should Learn Markdown" slug: "you-should-learn-markdown" """ struct SimpleYamlValue: Parser { enum Output: Equatable { case array([String]) case bool(Bool) case date(year: Int, month: Int, day: Int) case string(String) } var body: some Parser { OneOf { // YamlList().map { Output.array($0) } DateParser() Bool.parser().map(.case(Output.bool)) PrefixUpTo("\n".utf8).map(.string).map(.case(Output.string)) Rest().map(.string).map(.case(Output.string)) } } struct DateParser: Parser { var body: some Parser { Parse { Digits(4) "-".utf8 Digits(2) "-".utf8 Digits(2) }.map(.case(Output.date)) } } } struct SimpleYamlParser: Parser { typealias Output = [String: SimpleYamlValue.Output] var body: some Parser { Many(into: Output()) { (dict: inout Output, pair: (String, SimpleYamlValue.Output)) in let (key, value) = pair dict[key] = value } element: { // Parses a key and array. OneOf { Parse { PrefixUpTo(":".utf8).map(.string) ":\n".utf8 Many(into: [String]()) { array, string in array.append(string) } element: { From(.substring) { Whitespace() } "-".utf8 From(.substring) { Whitespace() } PrefixUpTo("\n".utf8).map(.string) } separator: { "\n".utf8 } // terminator: { // OneOf { // Peek { PrefixUpTo(":".utf8) } // End() // } // } } .map { ($0.0, SimpleYamlValue.Output.array($0.1)) } // Parse a key and a single value. Parse { PrefixUpTo(":".utf8).map(.string) ":".utf8 Whitespace() SimpleYamlValue() } } } separator: { "\n".utf8 } terminator: { End() } } } let simpleYamlString = #""" author: Michael Housh copy: true draft: false date: 2023-10-21 lastmod: 2023-10-21 image: banner.png featuredImage: banner.png test: - HVAC - General - Programming foo: Bar """# var keyedList = """ test: - HVAC - General - Programming foo: Bar """[...].utf8 // let parsedList = try keyedListParser.parse(&keyedList) // print(parsedList) let parsed = try SimpleYamlParser().parse(simpleYamlString[...].utf8) // let parsed = try SimpleYamlParser().parse(yamlString[...].utf8) for (key, value) in parsed { print("\(key): \(value)") } // assert(parsed.keys.count == 10) // try print(SimpleYamlParser().parse(simpleYamlString[...].utf8))