Split the six files that declared multiple sibling types under one namespace extension so each file declares exactly one top-level type: the Tagged node component types (Node, NodeKind, Scalar, Sequence, Mapping, Pair), the validation report types (Report, Source, SourceReport, BatchReport), DiagnosticKind, TokenKind, ScannerFlowContext kind, and the event-stream composer helpers. Public type names are unchanged; the shared report-rendering helpers move from file-private to internal so the split report types still reach them. Make check-namespacing.sh namespace-aware: the previous column-anchored scan was blind to types declared inside indented extension blocks, so it passed while the rule was violated. It now counts direct members of a PureYAML namespace extension and ignores nested types and private helpers.
112 lines
3.6 KiB
Swift
112 lines
3.6 KiB
Swift
public extension PureYAML.Validation {
|
|
/// Non-throwing aggregate report for validating many YAML inputs.
|
|
struct BatchReport: Equatable, Sendable, CustomStringConvertible {
|
|
public var sourceReports: [SourceReport]
|
|
public var failOnWarnings: Bool
|
|
|
|
public init(
|
|
sourceReports: [SourceReport],
|
|
failOnWarnings: Bool = false,
|
|
) {
|
|
self.sourceReports = sourceReports
|
|
self.failOnWarnings = failOnWarnings
|
|
}
|
|
|
|
public var fileCount: Int {
|
|
sourceReports.count
|
|
}
|
|
|
|
public var validCount: Int {
|
|
sourceReports.count(where: { !$0.invalid })
|
|
}
|
|
|
|
public var invalidCount: Int {
|
|
sourceReports.count(where: { $0.invalid })
|
|
}
|
|
|
|
public var diagnosticCount: Int {
|
|
sourceReports.reduce(0) { count, sourceReport in
|
|
count + sourceReport.report.diagnostics.count
|
|
}
|
|
}
|
|
|
|
public var isValid: Bool {
|
|
invalidCount == 0
|
|
}
|
|
|
|
public var diagnostics: [Diagnostic] {
|
|
sourceReports.flatMap(\.report.diagnostics)
|
|
}
|
|
|
|
public var description: String {
|
|
diagnostics.map(\.description).joined(separator: "\n")
|
|
}
|
|
|
|
public func markdownDescription(
|
|
title: String = "PureYAML Validation Report",
|
|
) -> String {
|
|
var lines: [String] = [
|
|
"# \(title)",
|
|
"",
|
|
"- Files: \(fileCount)",
|
|
"- Valid: \(validCount)",
|
|
"- Invalid: \(invalidCount)",
|
|
"- Diagnostics: \(diagnosticCount)",
|
|
"- Warnings fail: \(failOnWarnings ? "yes" : "no")",
|
|
"",
|
|
]
|
|
|
|
for sourceReport in sourceReports {
|
|
lines.append("## \(sourceReport.name)")
|
|
lines.append("")
|
|
lines.append("Status: \(sourceReport.invalid ? "invalid" : "valid")")
|
|
lines.append("")
|
|
|
|
if sourceReport.report.isEmpty {
|
|
lines.append("No diagnostics.")
|
|
} else {
|
|
lines.append("```text")
|
|
lines.append(sourceReport.report.description)
|
|
lines.append("```")
|
|
}
|
|
|
|
lines.append("")
|
|
}
|
|
|
|
return lines.joined(separator: "\n")
|
|
}
|
|
|
|
public func modelValue(
|
|
title: String = "PureYAML Validation Report",
|
|
) -> PureYAML.Model.Value {
|
|
.mapping(.init([
|
|
.init(key: "title", value: .string(title)),
|
|
.init(key: "summary", value: summaryModelValue),
|
|
.init(key: "sources", value: .sequence(sourceReports.map { $0.modelValue() })),
|
|
]))
|
|
}
|
|
|
|
public func yamlDescription(
|
|
title: String = "PureYAML Validation Report",
|
|
) -> String {
|
|
PureYAML.dump(modelValue(title: title))
|
|
}
|
|
|
|
public func jsonDescription(
|
|
title: String = "PureYAML Validation Report",
|
|
) -> String {
|
|
modelValue(title: title).jsonDescription + "\n"
|
|
}
|
|
|
|
private var summaryModelValue: PureYAML.Model.Value {
|
|
.mapping(.init([
|
|
.init(key: "files", value: .int(fileCount)),
|
|
.init(key: "valid", value: .int(validCount)),
|
|
.init(key: "invalid", value: .int(invalidCount)),
|
|
.init(key: "diagnostics", value: .int(diagnosticCount)),
|
|
.init(key: "warningsFail", value: .bool(failOnWarnings)),
|
|
]))
|
|
}
|
|
}
|
|
}
|