Type-safe extendable Swift DSL to validate your objects.
Heavily inspired by Kotlin valiktor.
Swift 5.4 DSL to create a validator for the value.
DSL begins with two top level functions validate and validateAny that conjunction and disjunction sematnics model.
In case of a validation failure ValidationError error will be thrown.
XCTAssertNoThrow {
try validate(user) {
validate(\.id).isPositive()
validate(\.email) {
isNotEmpty()
isEmail()
}
validate(\.dateString) { // validateAny(\.dateString) also works
any {
isDate(dateDecodingStrategy: .iso8601)
isDate(dateDecodingStrategy: .secondsSince1970)
}
}
}
}// In your `Package.swift`
dependencies: [
.package(url: "https://github.com/artbobrov/SwiftValidation", .branch("main")),
...
],
targets: [
.target(
name: ...,
dependencies: [
.product(name: "Example", package: "SwiftValidation"),
...
]
),
...
]Validation can throw ValidationError.
KeyPath can be named explicitly by validate(\.age, name: "age").equals(to: 23) then the error will be PartialValidationError with PartialValidationError.propertyName == "age".
Nested validation is supported.
try validate(user) {
validate(\.company, name: "company") {
validate(\.catchPhrase, name: "catchPhrase").isNotEmpty()
}
}In case of empty catchPhrase the propertyName equals to company.catchPhrase
DisjunctionValidator has similar semantic to boolean disjunction operations.
At least one validator should accept the object to not fail.
In case of empty validators validation does nothing.
ConjunctionValidator has similar semantic to boolean conjunction operations.
All validators should accept the object to not fail.
In case of empty validators validation does nothing.
Create a function returning object implementing Validator protocol. Associated type Value is a type you want to validate.
To support dot notation create extension of ExtendableValidator. Associated type Element is a type you want to validate.