Skip to content

Instantly share code, notes, and snippets.

@mikekavouras
Created November 29, 2016 01:18
Show Gist options
  • Save mikekavouras/4d9f6936582a42488aa73b76abe9985f to your computer and use it in GitHub Desktop.
Save mikekavouras/4d9f6936582a42488aa73b76abe9985f to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import Foundation
enum ValidatorResult {
case valid
case invalid(error: Error)
}
protocol Validator {
func validateValue(_ value: String) -> ValidatorResult
}
enum EmailValidatorError: Error {
case empty
case invalidFormat
}
enum PasswordValidatorError: Error {
case empty
case tooShort
case noUppercaseLetter
case noLowercaseLetter
case noNumber
}
struct EmptyStringValidator: Validator {
private let invalidError: Error
init(invalidError: Error) {
self.invalidError = invalidError
}
func validateValue(_ value: String) -> ValidatorResult {
return value.isEmpty ? .invalid(error: invalidError) : .valid
}
}
struct PasswordLengthValidator: Validator {
func validateValue(_ value: String) -> ValidatorResult {
if value.characters.count >= 8 {
return .valid
} else {
return .invalid(error: PasswordValidatorError.tooShort)
}
}
}
struct UppercaseLetterValidator: Validator {
func validateValue(_ value: String) -> ValidatorResult {
let uppercaseRegex = ".*[A-Z]+.*"
let uppercaseLetterTest = NSPredicate(format: "SELF MATCHES %@", uppercaseRegex)
if uppercaseLetterTest.evaluate(with: value){
return .valid
} else {
return .invalid(error: PasswordValidatorError.noUppercaseLetter)
}
}
}
struct CompositeValidator: Validator {
private let validators: [Validator]
init(validators: [Validator]) {
self.validators = validators
}
func validateValue(_ value: String) -> ValidatorResult {
for validator in validators {
switch validator.validateValue(value) {
case .valid: break
case .invalid(let error):
return .invalid(error: error)
}
}
return .valid
}
}
let emailValidator: Validator = {
let validator = EmptyStringValidator(invalidError: EmailValidatorError.empty)
return CompositeValidator(validators: [validator])
}()
let passwordValidator: Validator = {
let emptyValidator = EmptyStringValidator(invalidError: PasswordValidatorError.empty)
let lengthValidator = PasswordLengthValidator()
let uppercaseValidator = UppercaseLetterValidator()
let strengthValidator = CompositeValidator(validators: [lengthValidator, uppercaseValidator])
return CompositeValidator(validators: [emptyValidator, strengthValidator])
}()
emailValidator.validateValue("")
emailValidator.validateValue("[email protected]")
passwordValidator.validateValue("")
passwordValidator.validateValue("pudge")
passwordValidator.validateValue("thisismypassword")
passwordValidator.validateValue("thisIsMyPassword!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment