diff --git a/Sources/main.swift b/Sources/main.swift index 6a462ad..ef6b584 100644 --- a/Sources/main.swift +++ b/Sources/main.swift @@ -1,7 +1,8 @@ import Foundation @preconcurrency import Parsing -let yamlString = """ +var yamlString = """ +--- author: Michael Housh categories: - HVAC @@ -18,128 +19,96 @@ tags: - General - Programming title: "You Should Learn Markdown" -""" +"""[...].utf8 -_ = """ -series: - - General -title: "You Should Learn Markdown" -slug: "you-should-learn-markdown" -""" +struct YamlString: Parser { -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 { + 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)) + "\"".utf8 + PrefixUpTo("\"".utf8) + "\"".utf8 + }.map(.string) + + Prefix { $0 != UInt8(ascii: "\n") }.map(.string) } } } -struct SimpleYamlParser: Parser { +struct YamlObject: Parser { - typealias Output = [String: SimpleYamlValue.Output] + enum Value { + case array([String]) + case boolean(Bool) + case date(YamlDate.Output) + case string(String) + } - var body: some Parser { - Many(into: Output()) { (dict: inout Output, pair: (String, SimpleYamlValue.Output)) in - let (key, value) = pair - dict[key] = value + var body: some Parser { + "---".utf8 + Many(into: [String: Value]()) { (dict: inout [String: Value], pair: (String, Value)) in + dict[pair.0] = pair.1 } element: { - // Parses a key and array. + PrefixUpTo(":".utf8).map(.string) + ":".utf8 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)) } + "\n".utf8 + YamlArray() + }.map { Value.array($0) } - // Parse a key and a single value. Parse { - PrefixUpTo(":".utf8).map(.string) - ":".utf8 Whitespace() - SimpleYamlValue() + Bool.parser().map { Value.boolean($0) } + } + + Parse { + Whitespace() + YamlDate().map { Value.date($0) } + } + + Parse { + Whitespace() + YamlString().map { Value.string($0) } } } } 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)") +struct YamlArray: Parser { + var body: some Parser { + Many(into: [String]()) { array, string in + array.append(string) + } element: { + Whitespace(.horizontal) + "- ".utf8 + Prefix { $0 != UInt8(ascii: "\n") }.map(.string) + } separator: { + "\n".utf8 + } + } } -// assert(parsed.keys.count == 10) +struct YamlDate: Parser { + struct Output { + let year: Int + let month: Int + let day: Int + } -// try print(SimpleYamlParser().parse(simpleYamlString[...].utf8)) + var body: some Parser { + Parse(.memberwise(Output.init)) { + Digits(4) + "-".utf8 + Digits(2) + "-".utf8 + Digits(2) + } + } +} + +try print(YamlObject().parse(&yamlString))