diff --git a/src/commonMain/kotlin/io/konform/validation/types/ValidateAll.kt b/src/commonMain/kotlin/io/konform/validation/types/ValidateAll.kt index 95b77b9..44b8d6f 100644 --- a/src/commonMain/kotlin/io/konform/validation/types/ValidateAll.kt +++ b/src/commonMain/kotlin/io/konform/validation/types/ValidateAll.kt @@ -22,6 +22,7 @@ public class ValidateAll( override fun toString(): String = "ValidateAll(validation=$validations)" } +/** Validation that runs multiple validations in sequence and returns all validation errors. */ public class FailFastValidation( private val validations: List>, ) : Validation { diff --git a/src/commonMain/kotlin/io/konform/validation/types/ValidationAny.kt b/src/commonMain/kotlin/io/konform/validation/types/ValidationAny.kt new file mode 100644 index 0000000..74a5789 --- /dev/null +++ b/src/commonMain/kotlin/io/konform/validation/types/ValidationAny.kt @@ -0,0 +1,34 @@ +package io.konform.validation.types + +import io.konform.validation.Invalid +import io.konform.validation.Valid +import io.konform.validation.Validation +import io.konform.validation.ValidationResult +import io.konform.validation.flattenNotEmpty +import io.konform.validation.flattenOrValid + +public class ValidationAny( + private val validations: List>, + private val aggregateInvalidResults: (List) -> Invalid = List::flattenNotEmpty, +) : Validation { + override fun validate(value: T): ValidationResult { + val errors = mutableListOf() + for (validation in validations) { + when (val result = validation.validate(value)) { + // We only need 1 validation to succeed the "any" validation + is Valid -> return result + is Invalid -> errors + result + } + } + return errors.flattenOrValid(value) + } + + override fun toString(): String = "ValidationAny(validation=$validations)" + + private companion object { + private fun defaultAggregateInvalidResults(invalids: List): Invalid { + val combinedErrors = + "all validations failed: ${invalids.flatMap { invalid -> invalid.errors.map { it.message } }}" + } + } +} diff --git a/src/commonTest/kotlin/io/konform/validation/validationbuilder/ValidateAnyTest.kt b/src/commonTest/kotlin/io/konform/validation/validationbuilder/ValidateAnyTest.kt new file mode 100644 index 0000000..3999030 --- /dev/null +++ b/src/commonTest/kotlin/io/konform/validation/validationbuilder/ValidateAnyTest.kt @@ -0,0 +1,26 @@ +package io.konform.validation.validationbuilder + +import io.konform.validation.Validation +import io.konform.validation.constraints.maxLength +import io.konform.validation.constraints.minLength +import kotlin.test.Test + +class ValidateAnyTest { + @Test + fun validateAny() { + val validation = + Validation { + oneOf( + "must be either length 5 or 10", + { + minLength(5) + maxLength(5) + }, + { + minLength(10) + maxLength(10) + }, + ) + } + } +}