Am I missing something here? I cannot see a reason that this would not compile...
protocol StringValidationRule {
func validate(string: String) throws -> Bool
var errorType: StringValidationError { get }
}
extension Array where T: StringValidationRule {
func validateEach(string: String, completion: (valid: Bool, error: StringValidationError?) -> ()) {
for rule in self {
do {
try rule.validate(string)
completion(valid: true, error: nil)
} catch let error as StringValidationError {
completion(valid: false, error: error)
} catch {
fatalError("Unexpected error type")
}
}
}
}
var validationRules = ...
validationRules.validateEach("") { (valid, error) -> () in
}
Line 23 throws the following error:
error: cannot invoke 'validateEach' with an argument list of type '(String, (_, _) -> ())'
validationRules.validateEach("") { (valid, error) -> () in
AFAIK, extensions with where clauses only work with protocols. So, instead of extending Array, I would extend the CollectionType protocol. This way, your logic will work for all implementations of CollectionType, including Array.
The code is below. You can try it out in a Swift 2 playground.
typealias StringValidationError = String
protocol StringValidationRuleType {
func validate(string: String) throws -> Bool
}
extension CollectionType where Generator.Element: StringValidationRuleType {
func validateEach(string: String, completion: (valid: Bool, error: StringValidationError?) -> ()) {
for rule in self {
do {
try rule.validate(string)
completion(valid: true, error: nil)
} catch let error as StringValidationError {
completion(valid: false, error: error)
} catch {
fatalError("Unexpected error type")
}
}
}
}
struct StringValidationRule: StringValidationRuleType {
let valid: Bool
func validate(string: String) throws -> Bool {
return true
}
}
var validationRules = [StringValidationRule(valid: true), StringValidationRule(valid: true)]
validationRules.validateEach("") { (valid, error) -> () in { }}
== Matthias