Type-based input validation
try Ensure<PackageIsCool>(wrappedValue: packages.ensure)
A Validator
is a type that validates an input. You can create a Validator
like so:
struct GreaterThanZero : Validator {
static func validate(_ value: Int) throws {
guard value > 0 else { throw ValidationError("must be > 0") }
}
}
There are tons of built-in validators. You can combine them using various operations:
Not<EqualTo<Int._5>>.And<GreaterThanZero>
A DependentType
is a type that represents a value. Several are provided for some builtin types:
Int._0 // 0
Double._10 // 10
String.Space // " "
Bool.True // true
You can create a custom DependentType
by implementing the protocol:
extension String {
enum HelloWorld : DependentType {
public static let value: String = "Hello, world!"
}
}
// value > 0 && value < 5
GreaterThan<Int._0>.And<LessThan<Int._5>>
// value < 0 || value > 5
LessThan<Int._0>.Or<GreaterThan<Int._5>>
Not<EqualTo<Int._0>> // value != 0
EqualTo<Int._5> // == 5
EqualTo<String.HelloWorld> // == "Hello, world!"
LessThan<Int._5> // < 5
GreaterThan<Int._5> // > 5
LessThanOrEqualTo<Int._5> // <= 5
GreaterThanOrEqualTo<Int._5> // >= 5
// [String].count > 5
Array<String>.CountIs<GreaterThan<Int._5>>
// [String].map(\.count).contains(5)
Array<String>.Mapped<Array<Int>.Count, Array<Int>.Contains<Int._5>>
Not<String.IsEmpty> // !String.isEmpty
// [String].contains("Hello, world!")
Array<String>.Contains<String.HelloWorld>
// [String].contains(where: { $0.count > 0 })
Array<String>.ContainsWhere<String.CountIs<GreaterThan<Int._0>>>
// [String].allSatisfy { $0.count > 0 }
Array<String>.AllSatisfy<String.CountIs<GreaterThan<Int._0>>>
// [String].map(\.count).contains(5)
Array<String>.Mapped<Array<Int>.Count, Array<Int>.Contains<Int._5>>
// [Int].reduce(0, +) > 5
Array<Int>.Reduced<Int._0, Operator.Add, GreaterThan<Int._5>>
// value is String
Is<String>
// value is MyProtocol.Type
Is<MyProtocol.Type>