A swift package for creating validations, using ResultBuilder
syntax.
Validations with this library can be built by declaring Validation
types, using the built-in
types supplied with the library, or conforming your types to the Validatable
protocol.
Below is an example of using a validator that you define for a given type.
struct User {
let name: String
let email: String
}
let userValidator = ValidatorOf<User> {
Validator.validate(\.name, using: String.notEmpty())
Validator.validate(\.email) {
String.notEmpty()
String.contains("@")
}
}
try userValidator.validate(User(name: "Blob", email: "blob@example.com")) // success.
try userValidator.validate(User(name: "", email: "blob@example.com")) // throws error.
try userValidator.validate(User(name: "Blob", email: "blob.example.com")) // throws error.
ValidatorOf
is typealias ofValidator
for better ergonomics, however the above could also be written asValidator<User>
if you'd prefer.
You can conform types to the Validatable
protocol or AsyncValidatable
,
which are types that can validate an instance of itself.
Generally you will supply the Validation/body-swift.property-2e4vc
property. Which uses
result builder syntax.
extension User: Validatable {
var body: some Validator<Self> {
Validator {
Validator.validate(\.name, using: String.notEmpty())
Validator.validate(\.email) {
String.notEmpty()
String.contains("@")
}
}
}
}
try User(name: "Blob", email: "blob@example.com").validate() // success.
try User(name: "", email: "blob@example.com").validate() // throws error.
try User(name: "Blob", email: "blob.example.com").validate() // throws error.
However you can also implement the Validation/validate(_:)-lqpu
.
enum UserError: Error {
case invalidName
}
extension User: Validatable {
func validate(_ value: User) throws {
guard value.name != "" else {
throw UserError.invalidName
}
}
}
Read the api documentation here.