import Foundation import Yams /// A value being written into frontmatter. The engine emits these as minimal YAML scalars — /// it never round-trips a whole document through a YAML emitter. public enum FrontmatterValue: Sendable, Equatable { case string(String) case int(Int) case double(Double) case bool(Bool) case date(Date) /// Verbatim YAML supplied by the caller (flow collections, block scalars). Not validated. case raw(String) /// The scalar text placed after `key: `. public var yamlText: String { switch self { case let .string(value): Self.emitScalar(value) case let .int(value): String(value) case let .double(value): Self.emitDouble(value) case let .bool(value): value ? "true" : "false" case let .date(value): value.formatted(.iso8601) case let .raw(value): value } } var parsedValue: YAMLValue { switch self { case let .string(value): .string(value) case let .int(value): .int(value) case let .double(value): .double(value) case let .bool(value): .bool(value) case let .date(value): .date(value) case let .raw(value): if let node = try? Yams.compose(yaml: value) { YAMLValue(node) } else { .string(value) } } } } extension FrontmatterValue { private static func emitDouble(_ value: Double) -> String { if value.isNaN { return ".nan" } if value.isInfinite { return value < 0 ? "-.inf" : ".inf" } if value == value.rounded(), abs(value) < 1e15 { return String(Int64(value)) } return String(value) } /// Plain when YAML round-trips it back to the same string, double-quoted otherwise. /// The round-trip check is the authority: it catches leading/trailing space, comment /// introducers, and anything that would resolve to a bool/int/float/null/timestamp. static func emitScalar(_ value: String) -> String { guard !value.isEmpty, !value.unicodeScalars.contains(where: { $0 == "\n" || $0 == "\r" }) else { return quoted(value) } guard let node = try? Yams.compose(yaml: "v: \(value)"), let mapping = node.mapping, let scalar = mapping["v"], Resolver.default.resolveTag(of: scalar) == .str, scalar.scalar?.string == value else { return quoted(value) } return value } private static func quoted(_ value: String) -> String { var out = "\"" for scalar in value.unicodeScalars { switch scalar { case "\\": out += "\\\\" case "\"": out += "\\\"" case "\n": out += "\\n" case "\r": out += "\\r" case "\t": out += "\\t" default: if scalar.value < 0x20 || scalar.value == 0x7F { out += String(format: "\\x%02x", scalar.value) } else { out.unicodeScalars.append(scalar) } } } return out + "\"" } }