Slice 1 of #92. Introduce the OpenAPIKit-idiom validation framework, replacing the imperative if-tree structural validator: - ValidationError (reason + coding path) renders "<reason> at path: root/row/cell"; ValidationErrorCollection gathers every failure and is thrown once. - Validation<Subject, Document> is the atomic, composable rule value, with the multi-error and single-error Bool inits (the latter auto-forms "Failed to satisfy: <description>"). Predicate-gated, type-directed via an erased AnyValidation that guards an optional from matching a non-optional rule. - The framework is parameterized over both Subject and Document so the structural, DTD, XSD, and Schematron layers share one machinery (Document = Void for rules that need only their subject). - Validator<Document> walks the node tree, building the coding path, with blank / default factories and fluent validating / withoutValidating. - The combinator algebra (&&, ||, comparison lifts, take, lift, unwrap, all) as free functions returning closures. The structural duplicate-attribute rule is reborn as Validation<Element, Void>. Combinators and the erased wrapper are unit-tested as pure functions per the rule. The legacy Validation.Issue stays only for the not-yet-migrated schema validators and is retired in a later slice.
19 lines
567 B
Swift
19 lines
567 B
Swift
public extension PureXML.Validation {
|
|
/// A single validation finding with a severity and human-readable message.
|
|
struct Issue: Equatable, Hashable, Sendable, CustomStringConvertible {
|
|
public var severity: Severity
|
|
public var message: String
|
|
|
|
public init(severity: Severity, message: String) {
|
|
self.severity = severity
|
|
self.message = message
|
|
}
|
|
|
|
public var description: String {
|
|
"\(severity.rawValue): \(message)"
|
|
}
|
|
}
|
|
}
|
|
|
|
extension PureXML.Validation.Issue: Swift.Error {}
|