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 series: - General tags: - HVAC - General - Programming --- """ _ = """ title: "You Should Learn Markdown" slug: "you-should-learn-markdown" """ enum YamlItem { case boolean(Bool) case date(year: Int, month: Int, day: Int) case string(String) private static let dateParser = Parse(input: Substring.self) { Digits(4) "-" Digits(2) "-" Digits(2) }.map { Self.date(year: $0.0, month: $0.1, day: $0.2) } private static let booleanParser = Parse(input: Substring.self) { Bool.parser() }.map { Self.boolean($0) } private static let quotedString = Parse(input: Substring.self) { "\"" PrefixUpTo("\"") "\"" } private static let stringParser = Parse(input: Substring.self) { OneOf { quotedString Rest() } }.map { Self.string(String($0)) } static let parser = OneOf { dateParser booleanParser stringParser } } enum YamlLine { case keyValue(String, YamlItem) case list(String, [String]) static let parser = OneOf { listParser keyValueParser } static let keyParser = Parse(input: Substring.self) { PrefixUpTo(":") ":" }.map(String.init) static let keyValueParser = Parse(input: Substring.self) { PrefixUpTo(":").map(String.init) ": " YamlItem.parser }.map { YamlLine.keyValue($0.0, $0.1) } static let listLineParser = Parse(input: Substring.self) { Skip { PrefixThrough("- ") } PrefixUpTo("\n").map(String.init) "\n" } static let listParser = Parse(input: Substring.self) { PrefixUpTo(":\n").map(String.init) ":\n" Many { Skip { PrefixThrough("- ") } PrefixUpTo("\n").map(String.init) "\n" } } .map { YamlLine.list($0.0, $0.1) } } let yamlBlockParser = Parse(input: Substring.UTF8View.self) { "---\n".utf8 Many { PrefixUpTo("\n".utf8) // From(.substring) { YamlLine.parser } } separator: { "\n".utf8 } "\n".utf8 "---".utf8 } // let yamlLineParser = Parse(input: Substring.UTF8View.self) { // PrefixUpTo(":".utf8).map(String.init) // ":".utf8 // OneOf { // PrefixUpTo("\n".utf8) // Rest() // }.map(String.init) // } let stringLine = #"author: "Michael Housh""# // let parsedLine = try yamlLineParser.parse(stringLine[...].utf8) // print(parsedLine) let stringItem = "foo" let quotedItem = "\"foo\"" let dateItem = "2025-01-29" let boolItem = "true" try print(YamlItem.parser.parse(stringItem[...])) try print(YamlItem.parser.parse(quotedItem[...])) try print(YamlItem.parser.parse(dateItem[...])) try print(YamlItem.parser.parse(boolItem[...])) let kvLine = "author: Michael Housh" var listLine = """ test: - HVAC - General - Programming """[...] try print(YamlLine.parser.parse(kvLine[...])) try print(YamlLine.parser.parse(&listLine)) print(listLine) // try print(YamlItem.parser.parse(listItem[...])) var yamlLines = """ author: Michael Housh test: - HVAC - General - Programming """[...] let lineParser = Many { YamlLine.parser } separator: { "\n" } try print(lineParser.parse(yamlLines)) // let lines = try yamlBlockParser.parse(yamlString[...].utf8) // // for line in lines { // print("line: \(String(line)!)") // if let parsed = try? YamlLine.keyValueParser.parse(Substring(line)) { // print(parsed) // } else { // if let key = try? YamlLine.keyParser.parse(Substring(line)) { // print("found key: \(String(key))") // } else { // print("not key value.") // } // } // } // print(lines.map(String.init)) // print(lines)