The validation module already implemented the composable-rule idiom under its own names (Check/Issue/SubjectContext) and a value-type Validator with duplicated traversal machinery per layer. Renamed the core types to the canonical names (Validation/ValidationError/ValidationErrorCollection/ ValidationContext/BuiltinValidation/AnyValidation), converted Validator to a reference-type class with the two-tier default-rule split, and genericized it over both Subject and Document via a new Traversable protocol so the model and tagged layers share one walk engine instead of two copies. Wired the JSON-representability rule set into the same shape and closed the two missing pieces (unwrap combinator, JSON coverage/config-pin tests).
39 lines
2.2 KiB
Swift
39 lines
2.2 KiB
Swift
import PureYAML
|
|
|
|
public extension PureYAML.JSON {
|
|
/// JSON-representability checks built on PureYAML's own validation framework.
|
|
/// The parser already guarantees the input is well-formed YAML (and so covers
|
|
/// JSON syntax); this layer reports the value-level reasons a tree cannot be
|
|
/// emitted as JSON: a non-string mapping key, a non-finite number, or (for a
|
|
/// deterministic single-meaning document) a duplicate key.
|
|
///
|
|
/// JSON the format tolerates duplicate object names, but a tree that carries two
|
|
/// pairs with the same key emits an ambiguous document, so the representability
|
|
/// validator rejects duplicates for determinism. Drop ``PureYAML/Validation/BuiltinValidation/mappingKeysAreUnique``
|
|
/// from the rule set if you want the permissive reading.
|
|
enum Validator {
|
|
/// The full JSON-representability rule set: unique keys, string keys, finite
|
|
/// numbers. Suitable to pass straight to `PureYAML.JSON.Convert`. Built with
|
|
/// the same tiered `Validator` shape every other layer uses, so it carries the
|
|
/// same `.blank`/`.validating`/`.withoutValidating`/`.validationDescriptions`
|
|
/// machinery (validation-rules.md, principle 10).
|
|
public static var representability: PureYAML.Validation.Validator<PureYAML.Model.Value, PureYAML.Model.Value> {
|
|
PureYAML.Validation.Validator(nonReferenceDefaultValidations: [
|
|
PureYAML.Validation.AnyValidation(PureYAML.Validation.BuiltinValidation.mappingKeysAreUnique),
|
|
PureYAML.Validation.AnyValidation(PureYAML.Validation.BuiltinValidation.mappingKeysAreStrings),
|
|
PureYAML.Validation.AnyValidation(PureYAML.Validation.BuiltinValidation.numbersAreFinite),
|
|
])
|
|
}
|
|
|
|
/// Every reason the value cannot be emitted as strict JSON, in document order.
|
|
public static func issues(for value: PureYAML.Model.Value) -> [PureYAML.Validation.ValidationError] {
|
|
representability.collect(value).values
|
|
}
|
|
|
|
/// Whether the value can be emitted as strict JSON.
|
|
public static func isRepresentable(_ value: PureYAML.Model.Value) -> Bool {
|
|
issues(for: value).isEmpty
|
|
}
|
|
}
|
|
}
|