public extension PureYAML.Validation { /// A type-directed validation value (the `Validation` of the validation idiom): 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 Check: Sendable { public let description: String public let predicate: @Sendable (SubjectContext) -> Bool public let check: @Sendable (SubjectContext) -> [Issue] /// Multi-error form: return one issue per problem. Use when a subject can fail several ways. public init( description: String, check: @escaping @Sendable (SubjectContext) -> [Issue], when predicate: @escaping @Sendable (SubjectContext) -> 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 issue `"Failed to satisfy: "`. The dominant form. public init( description: String, severity: Severity = .error, check: @escaping @Sendable (SubjectContext) -> Bool, when predicate: @escaping @Sendable (SubjectContext) -> Bool = { _ in true }, ) { self.init( description: description, check: { context in check(context) ? [] : [Issue(severity: severity, reason: "Failed to satisfy: \(description)", path: context.path)] }, when: predicate, ) } /// Gates on the predicate, then runs the check. public func apply(_ context: SubjectContext) -> [Issue] { guard predicate(context) else { return [] } return check(context) } } }