PureYAML/Sources/Validation/Validation.BatchReport.swift
Mihaela M c4f7f9dccc refactor(code-style): one top-level type per source file
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.
2026-06-26 06:14:21 +02:00

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)),
]))
}
}
}