commonMain.io.konform.validation.ValidationResult.kt Maven / Gradle / Ivy
package io.konform.validation
import kotlin.reflect.KProperty1
interface ValidationError {
val dataPath: String
val message: String
}
internal data class PropertyValidationError(
override val dataPath: String,
override val message: String
) : ValidationError {
override fun toString(): String {
return "ValidationError(dataPath=$dataPath, message=$message)"
}
}
interface ValidationErrors : List
internal object NoValidationErrors : ValidationErrors, List by emptyList()
internal class DefaultValidationErrors(private val errors: List) : ValidationErrors, List by errors {
override fun toString(): String {
return errors.toString()
}
}
sealed class ValidationResult {
abstract operator fun get(vararg propertyPath: Any): List?
abstract fun map(transform: (T) -> R): ValidationResult
abstract val errors: ValidationErrors
}
data class Invalid(
internal val internalErrors: Map>) : ValidationResult() {
override fun get(vararg propertyPath: Any): List? =
internalErrors[propertyPath.joinToString("", transform = ::toPathSegment)]
override fun map(transform: (T) -> R): ValidationResult = Invalid(this.internalErrors)
private fun toPathSegment(it: Any): String {
return when (it) {
is KProperty1<*, *> -> ".${it.name}"
is Int -> "[$it]"
else -> ".$it"
}
}
override val errors: ValidationErrors by lazy {
DefaultValidationErrors(
internalErrors.flatMap { (path, errors ) ->
errors.map { PropertyValidationError(path, it) }
}
)
}
override fun toString(): String {
return "Invalid(errors=${errors})"
}
}
data class Valid(val value: T) : ValidationResult() {
override fun get(vararg propertyPath: Any): List? = null
override fun map(transform: (T) -> R): ValidationResult = Valid(transform(this.value))
override val errors: ValidationErrors
get() = DefaultValidationErrors(emptyList())
}