Skip to content

Commit

Permalink
add Custom Validator section to Validation docs (#935)
Browse files Browse the repository at this point in the history
<!-- Describe your changes clearly and use examples if possible. -->
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.
<!-- When this PR is merged, the title and body will be -->
Add 'How to create custom validators' to docs.
<!-- used to generate a release automatically. -->

---------

Co-authored-by: Tim Condon <0xTim@users.noreply.github.com>
  • Loading branch information
hsharghi and 0xTim committed Nov 9, 2023
1 parent 46150d9 commit 882b8a5
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions docs/basics/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
.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)
```

0 comments on commit 882b8a5

Please sign in to comment.