ValidatorOf

public struct ValidatorOf<Value, Error>

A type that acts as a generic wrapper around a validate function.

This type is the building block for all validations provided by the library.

When writing your own validators - either from scratch, or by composing existing ones - it is recommended that you encapsulate these by creating static variables (or functions, if your validator takes parameters) on extensions of ValidatorOf, constrainted to the type value type that the validator operates on.

You should also constrain your extension on the particular type of error that you return - in most cases this will simply be a String.

The following example shows you can define your own validator that operates on an Int:

extension ValidatorOf where Value == String, Error == String {
    static func myIntValidator(someParameter: Int) -> Self {
        return Self { value in
            // your validation logic
        }
    }
}

Defining your validators in this way allows you to pass an instance into anything that takes a ValidatorOf<Int, String> (such as the @Validating property wrapper) in concise form by taking advantage of Swift type-inference, e.g.:

@Validating(.myIntValidator(someParameter: 1))
  • A closure type that encapsulates validation logic.

    Declaration

    Swift

    public typealias Validator = (_ value: Value) -> Validated<Value, Error>

    Parameters

    value

    The value to be validated.

    Return Value

    The validation result, either .valid(Value) or .invalid(Error).

  • The validate function. Call this as a function to perform validation on a given value.

    Declaration

    Swift

    public let validate: Validator
  • Initialises an instance with the given Validator closure.

    Swift’s trailing closure syntax allows for validator types to be defined quite succinctly:

    let myIntValidator = ValidatorOf<Int, String> { value in
        // your validation logic here
    }
    

    Declaration

    Swift

    public init(validate: @escaping Validator)

    Parameters

    validate

    The validator function.

  • Returns a new validator derived from self that operates on values of type LocalValue.

    Validator pullback allows you to re-use existing validator logic that works on one type A against a different type B by providing a function that knows how to transform type B to A.

    For example, say you have an ageValidator that operates on type Int, a struct Person that has an age: Int property and you want to define a personValidator that validates the person’s age.

    Instead of writing a validator from scratch, you can simply use your existing ageValidator, pulled back to operate on type Person, providing a function that returns Person.age:

    let personValidator: ValidatorOf<Person, String> = ageValidator.pullback { person in person.age }
    

    Since Swift 5.2 allows you to pass a KeyPath as a function, the you can pass in any KeyPath<LocalValue, Value> instead:

    let personValidator: ValidatorOf<Person, String> = ageValidator.pullback(\.age)
    

    Declaration

    Swift

    public func pullback<LocalValue>(_ transform: @escaping (_ localValue: LocalValue) -> Value) -> ValidatorOf<LocalValue, Error>

    Parameters

    transform

    A function that converts some other type LocalValue to self’s Value type.

    localValue

    The value passed to validate on the derived validator.

    Return Value

    A new validator that operates on LocalValue.

  • Returns a new optional validator that operates on Value? instead of Value.

    This operator allows you to re-use an existing validator on non-optional types with an optional of the same type.

    This can be useful in situations where you cannot rely on the Swift type system to enforce optional behaviour, for example if you are capturing some user input that you require be non-nil but cannot use a non-optional type as there is no sensible default that you can use.

    Whenever possible, if you have a value that is required and you are able to provide a sensible default you should prefer to use the Swift type system to enforce it and use a non-optional property and validator.

    This generic form takes an optional error value that will be used to determine if a value is required in order to be valid.

    See

    See Also: optional(allowNil:)

    Declaration

    Swift

    public func optional(errorOnNil: Error?) -> ValidatorOf<Value?, Error>

    Parameters

    errorOnNil

    An optional error value. If an error value is given, nil values will be treated as invalid and the error value given will be used in the .invalid result. If no error value is given, nil values will always produce a .valid result.

  • Returns a validator that is the logical inverse of self.

    If you have some validator that performs some kind of boolean logic, you can easily produce a negated version using this operator.

    Example:

    let isTrue = ValidatorOf<Bool, String> {
        if $0 == true { return .valid(true) }
        return .error("must be true")
    }
    
    let isFalse = isTrue.negated(withError: "must be false")
    

    Declaration

    Swift

    public func negated(withError error: Error) -> ValidatorOf<Value, Error>

    Parameters

    error

    The error to use for the negated invalid case.

  • Returns a new validator whose errors are transformed by the provided closure.

    This operator can be used to modify or replace errors on an existing validator whilst not changing the actual validation logic itself.

    All validators that produce an invalid result will hold on to a non-empty array of errors although many will typically only have one error. In this case you can simply return a brand new error value from your transform closure and it will replace that single error.

    However, it is possible for a validator to hold more than one error, for instance, any validators that you have composed using combine. In this case, you should use this method to derive a new error from the existing one. If you need to replace all errors with a single error you should use reduceErrors instead.

    Declaration

    Swift

    public func mapErrors<LocalError>(_ transform: @escaping (_ error: Error) -> LocalError) -> ValidatorOf<Value, LocalError>

    Parameters

    transform

    A closure that is called with each error in turn and should return a new local error.

    error

    The error from the original validator.

    Return Value

    A new validator whose errors are automatically mapped.

  • Composes multiple validators into a single validator.

    This form takes a variadic list of validators/

    See

    See Also: combine(validators:)

    Declaration

    Swift

    public static func combine<Value, Error>(_ validators: ValidatorOf<Value, Error>...) -> ValidatorOf<Value, Error>
  • Composes an array of validators into a single validator.

    Returns a new validator that accumulates the results of each composed validator, returning a .valid result if all validators are valid or an .invalid result containing an aggregate of all errors if any of them are invalid.

    Declaration

    Swift

    public static func combine<Value, Error>(_ validators: [ValidatorOf<Value, Error>]) -> ValidatorOf<Value, Error>

    Parameters

    validators

    A homogenous collection of validators that operate on the same Value and Error.

    Return Value

    A new composite validator.

Available where Value == Bool, Error == String

  • Validates that a boolean value is true.

    Declaration

    Swift

    public static let isTrue: ValidatorOf<Bool, String>
  • Validates that a boolean value is false.

    Declaration

    Swift

    public static let isFalse: ValidatorOf<Bool, String>

Available where Value: Collection, Error == String

  • Validates the collection’s count against the given numeric validator.

    This validator allows you to flexibly validate the collection count using any other Int validator, for example:

    .hasLengthOf(.greaterThan(1))
    

    Declaration

    Swift

    public static func hasLengthOf(_ validator: ValidatorOf<Int, Error>) -> ValidatorOf<Value, Error>

    Parameters

    validator

    A numeric validator used to validate the collection’s count.

  • Validates the collection’s count is exactly the given value.

    This validator is a convenience and is equivalent to passing .isExactly(count) to hasLengthOf(validator:).

    Declaration

    Swift

    public static func hasLengthOf(_ count: Int) -> ValidatorOf<Value, Error>

    Parameters

    count

    The collection’s expected count.

Available where Value: Collection, Value.Element: Equatable, Error == String

  • Validate that the collection contains the given element.

    Declaration

    Swift

    public static func contains(_ element: Value.Element) -> ValidatorOf<Value, Error>

    Parameters

    element

    The element that the collection is expected to contain.

Available where Value: Comparable, Error == String

  • Validates that a value >= the given value.

    Declaration

    Swift

    public static func isAtLeast(_ minimum: Value) -> ValidatorOf<Value, Error>

    Parameters

    minimum

    The minimum expected value.

  • Validates that a value is <= the given value.

    Declaration

    Swift

    public static func isAtMost(_ maximum: Value) -> ValidatorOf<Value, Error>

    Parameters

    maximum

    The maximum expected value.

  • Validates that a value is < the given value.

    Declaration

    Swift

    public static func isLessThan(_ upperBound: Value) -> ValidatorOf<Value, Error>

    Parameters

    upperBound

    The amount that value should be less than.

  • Validates that a value is > the given value.

    Declaration

    Swift

    public static func isGreaterThan(_ lowerBound: Value) -> ValidatorOf<Value, Error>

    Parameters

    lowerBound

    The amount that the value should be greater than.

  • Validates that a value is within the given range.

    Declaration

    Swift

    public static func isInRange(_ range: ClosedRange<Value>) -> ValidatorOf<Value, Error>

    Parameters

    range

    A closed range that the value should be within.

  • Validates that a value is within the given range.

    Declaration

    Swift

    public static func isInRange(_ range: Range<Value>) -> ValidatorOf<Value, Error>

    Parameters

    range

    An unclosed range that the value should be within.

Available where Value: Equatable, Error == String

  • Validates that a value is in a given collection.

    This validation makes it possible to validate that a value is one of a given list of values.

    Declaration

    Swift

    public static func isIncluded(in collection: [Value]) -> ValidatorOf<Value, Error>

    Parameters

    collection

    An array of valid values.

  • Validates that a value is not in a given collection.

    This validation makes it possible to validate that a value is not one of a given list of values.

    Declaration

    Swift

    public static func isExcluded(from collection: [Value]) -> ValidatorOf<Value, Error>

    Parameters

    collection

    A list of invalid values.

Available where Value: Hashable, Error == String

  • Validates that a value is in a given collection.

    This validation makes it possible to validate that a value is one of a given list of values.

    Declaration

    Swift

    public static func isIncluded(in set: Set<Value>) -> ValidatorOf<Value, Error>

    Parameters

    collection

    An set of valid values.

  • Validates that a value is not in a given collection.

    This validation makes it possible to validate that a value is not one of a given list of values.

    Declaration

    Swift

    public static func isExcluded(from set: Set<Value>) -> ValidatorOf<Value, Error>

    Parameters

    collection

    A set of invalid values.

Available where Value: Equatable, Error == String

  • Validates that value is equal to another value.

    Declaration

    Swift

    public static func isEqualTo(_ other: Value) -> ValidatorOf<Value, Error>

    Parameters

    other

    The value to compare against.

Available where Value == Int, Error == String

  • Validates that the value is exactly the given amount.

    This validator is effectively the same as isEqualTo but with a slightly modified error message.

    Declaration

    Swift

    public static func isExactly(_ amount: Int) -> ValidatorOf<Value, Error>

    Parameters

    amount

    The amount that the value should equal.

  • Validates that a value is even.

    Declaration

    Swift

    public static let isEven: ValidatorOf<Int, String>
  • Validates that a value is odd.

    Declaration

    Swift

    public static let isOdd: ValidatorOf<Int, String>

Available where Value == String, Error == String

  • Validates that a string starts with a given prefix.

    Declaration

    Swift

    public static func beginsWith(_ prefix: String) -> ValidatorOf<Value, Error>

    Parameters

    prefix

    The expected prefix.

  • Validates that a string ends with a given suffix.

    Declaration

    Swift

    public static func endsWith(_ suffix: String) -> ValidatorOf<Value, Error>

    Parameters

    suffix

    The expected suffix.

  • Validates that the string’s length matches the given numeric validator.

    Declaration

    Swift

    public static func itsLength(_ validator: ValidatorOf<Int, Error>) -> ValidatorOf<Value, Error>

    Parameters

    validator

    Used to validate the string’s count

  • Validates that the string’s length is equal to the given length.

    This is shorthand for .itsLength(.isExactly(length)).

    Declaration

    Swift

    public static func hasLengthOf(_ length: Int) -> ValidatorOf<Value, Error>

    Parameters

    length

    The expected length.

  • Validates that a string matches the given pattern.

    This allows you to validate a string against a regular expression or any other supported string comparison type.

    Declaration

    Swift

    public static func matchesPattern(
        _ pattern: String,
        as options: NSString.CompareOptions = .regularExpression
    ) -> Self

    Parameters

    options

    String comparison options, defaults to using regular expressions.

  • Validates that string is an empty string (i.e. "").

    Declaration

    Swift

    public static let isEmpty: ValidatorOf<String, String>
  • Validates that a string is non-empty.

    Declaration

    Swift

    public static let isNotEmpty: ValidatorOf<String, String>

Available where Error == String

  • Returns a new optional validator that operates on Value? instead of Value.

    This operator allows you to re-use an existing validator on non-optional types with an optional of the same type.

    This operator is similar to optional(errorOnNil:) except instead of taking an error value, it simply takes a boolean to indicate whether nil is allowed. If allowNil is true then nil values will be treated as valid, otherwise they will be treated as invalid, using a default string error message.

    Whilst you could use mapErrors or reduceErrors to modify the default message, if you need to use a specific error you should use optional(errorOnNil:) and pass the required error directly.

    See

    See Also: optional(errorOnNil:)

    Declaration

    Swift

    public func optional(allowNil: Bool) -> ValidatorOf<Value?, Error>

    Parameters

    errorOnNil

    An optional error value. If an error value is given, nil values will be treated as invalid and the error value given will be used in the .invalid result. If no error value is given, nil values will always produce a .valid result.