From 882b8a521f520caf89722faf1c61d6ed1176cfed Mon Sep 17 00:00:00 2001 From: Hadi Sharghi Date: Thu, 9 Nov 2023 15:58:21 +0330 Subject: [PATCH] add Custom Validator section to Validation docs (#935) Add a section about Custom Validators, and a sample to create a custom validator for zip codes. The sample is from a code that @0xTim had been provided in an issue. Add 'How to create custom validators' to docs. --------- Co-authored-by: Tim Condon <0xTim@users.noreply.github.com> --- docs/basics/validation.md | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/basics/validation.md b/docs/basics/validation.md index 6519fcbd..610b639a 100644 --- a/docs/basics/validation.md +++ b/docs/basics/validation.md @@ -227,3 +227,66 @@ Validators can also be combined to build complex validations using operators. |`!`|prefix|Inverts a validator, requiring the opposite.| |`&&`|infix|Combines two validators, requires both.| |`||`|infix|Combines two validators, requires one.| + + + +## Custom Validators + +Creating a custom validator for zip codes allows you to extend the functionality of the validation framework. In this section, we'll walk you through the steps to create a custom validator for validating zip codes. + +First create a new type to represent the `ZipCode` validation results. This struct will be responsible for reporting whether a given string is a valid zip code. + +```swift +extension ValidatorResults { + /// Represents the result of a validator that checks if a string is a valid zip code. + public struct ZipCode { + /// Indicates whether the input is a valid zip code. + public let isValidZipCode: Bool + } +} +``` + +Next, conform the new type to `ValidatorResult`, which defines the behavior expected from a custom validator. + +```swift +extension ValidatorResults.ZipCode: ValidatorResult { + public var isFailure: Bool { + !self.isValidZipCode + } + + public var successDescription: String? { + "is a valid zip code" + } + + public var failureDescription: String? { + "is not a valid zip code" + } +} +``` + +Finally, implement the validation logic for zip codes. Use a regular expression to check whether the input string matches the format of a USA zip code. + +```swift +private let zipCodeRegex: String = "^\\d{5}(?:[-\\s]\\d{4})?$" + +extension Validator where T == String { + /// Validates whether a `String` is a valid zip code. + public static var zipCode: Validator { + .init { input in + guard let range = input.range(of: zipCodeRegex, options: [.regularExpression]), + range.lowerBound == input.startIndex && range.upperBound == input.endIndex + else { + return ValidatorResults.ZipCode(isValidZipCode: false) + } + return ValidatorResults.ZipCode(isValidZipCode: true) + } + } +} +``` + +Now that you've defined the custom `zipCode` validator, you can use it to validate zip codes in your application. Simply add the following line to your validation code: + +```swift +validations.add("zipCode", as: String.self, is: .zipCode) +``` +