Skip to content

Instantly share code, notes, and snippets.

@mcassiano
Last active June 23, 2020 21:53
Show Gist options
  • Save mcassiano/37f919148be80c3b4258657ad2829f75 to your computer and use it in GitHub Desktop.
Save mcassiano/37f919148be80c3b4258657ad2829f75 to your computer and use it in GitHub Desktop.
data class ValidationResult<E>(
val isValid: Boolean,
val errors: E
)
interface FieldValidator<I, O> {
fun validate(input: I): O
}
interface FormValidator<T, E> {
fun validate(form: T): ValidationResult<E>
}
class EmailFieldValidator(prival val resources: Resources) : FieldValidator<String, ValidationResult<String?>> {
override fun validate(input: String): ValidationResult<String?> {
val isValid = android.util.Patterns.EMAIL_ADDRESS.matcher(input).matches()
val errorMessage = if (!isValid) {
resources.getString(R.string.invalid_email)
} else {
null
}
return ValidationResult(isValid, errorMessage)
}
}
class NameFieldValidator(prival val resources: Resources) : FieldValidator<String, ValidationResult<String?>> {
override fun validate(input: String): ValidationResult<String?> {
val isValid = input.isNotBlank() && input.split(" ")
.fold(true) { _, slice -> slice.isNotBlank() }
val errorMessage = if (!isValid) {
resources.getString(R.string.full_name)
} else {
null
}
return ValidationResult(isValid, errorMessage)
}
}
class PasswordFieldValidator(prival val resources: Resources) : FieldValidator<Pair<String, String>, ValidationResult<String?>> {
override fun validate(input: Pair<String, String>): ValidationResult<String?> {
val isEmpty = input.first.isBlank() || input.second.isBlank()
val areDifferent = input.first != input.second
val errorMessage = when {
isEmpty -> {
resources.getString(R.string.empty)
}
areDifferent -> {
resources.getString(R.string.mismtach)
}
else -> {
null
}
}
return ValidationResult(!isEmpty && !areDifferent, errorMessage)
}
}
data class SignUpForm(
val name: String,
val email: String,
val password: String,
val passwordConfirmation: String
)
data class SignUpFormErrors(
val name: String?,
val email: String?,
val password: String?
)
class SignUpFormValidator(
@NameValidator private val nameFieldValidator: FieldValidator<String, ValidationResult<String?>>,
@EmailValidator private val emailFieldValidator: FieldValidator<String, ValidationResult<String?>>,
@PasswordValidator private val passwordFieldValidator: FieldValidator<Pair<String, String>, ValidationResult<String?>>
) : FormValidator<SignUpForm, SignUpFormErrors> {
override fun validate(form: SignUpForm): ValidationResult<SignUpFormErrors> {
val nameValidation = nameFieldValidator.validate(form.name)
val emailValidation = emailFieldValidator.validate(form.email)
val passwordValidation = passwordFieldValidator
.validate(Pair(form.password, form.passwordConfirmation))
val results = arrayOf(
nameValidation,
emailValidation,
passwordValidation
)
val errors = SignUpFormErrors(
nameValidation.errors,
emailValidation.errors,
passwordValidation.errors
)
return ValidationResult(results.all { it.isValid }, errors)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment