Last active
December 28, 2020 11:06
-
-
Save stinger/29c5cad1d759fb5f9a9967ebb285a612 to your computer and use it in GitHub Desktop.
Functional String validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func validate<T: Codable>(_ validator: @escaping (T) -> Bool) -> (T) -> Bool { | |
return { input in | |
return validator(input) | |
} | |
} | |
enum StringValidator: CustomStringConvertible { | |
case isNotEmpty | |
case lengthIn(ClosedRange<Int>) | |
var validator: (String) -> Bool { | |
return validate { input in | |
switch self { | |
case .isNotEmpty: | |
return !input.isEmpty | |
case .lengthIn(let lengthRange): | |
return lengthRange.contains(input.count) | |
} | |
} | |
} | |
var description: String { | |
switch self { | |
case .isNotEmpty: | |
return "Input should not be empty" | |
case .lengthIn(let lengthRange): | |
return "Input should be between \(lengthRange.lowerBound) and \(lengthRange.upperBound) characters long" | |
} | |
} | |
} | |
extension String { | |
func failedValidators(in validators: StringValidator...) -> [StringValidator] { | |
return validators.filter { !$0.validator(self) } | |
} | |
} | |
/// Usage | |
let input = "Test" | |
print("Input: \"\(input)\"") | |
let failed = input.failedValidators(in: .isNotEmpty, .lengthIn(5...40)) | |
/// Should be an error regarding the length | |
print("is valid:", failed.isEmpty) | |
if !failed.isEmpty { | |
print(failed.map { $0.description }.joined(separator: "\n")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment