public extension PureYAML.Validation { /// A type-directed validation value: a positive `description`, a `predicate` that gates /// application, and a multi-error `check`. It is applied only to values of type `Subject`, anywhere /// they occur in the traversed tree. `Document` is the type of the validated tree's root, the same /// for every check a given validator runs. struct Validation: Sendable { public let description: String public let predicate: @Sendable (ValidationContext) -> Bool public let check: @Sendable (ValidationContext) -> [ValidationError] /// Multi-error form: return one error per problem. Use when a subject can fail several ways. public init( description: String, check: @escaping @Sendable (ValidationContext) -> [ValidationError], when predicate: @escaping @Sendable (ValidationContext) -> Bool = { _ in true }, ) { self.description = description self.predicate = predicate self.check = check } /// Single-error Bool form: a positive description plus a check whose `false` auto-produces the /// one error `"Failed to satisfy: "`. The dominant form. public init( description: String, severity: Severity = .error, check: @escaping @Sendable (ValidationContext) -> Bool, when predicate: @escaping @Sendable (ValidationContext) -> Bool = { _ in true }, ) { self.init( description: description, check: { context in check(context) ? [] : [ValidationError(severity: severity, reason: "Failed to satisfy: \(description)", path: context.path)] }, when: predicate, ) } /// Gates on the predicate, then runs the check. public func apply(_ context: ValidationContext) -> [ValidationError] { guard predicate(context) else { return [] } return check(context) } } }