All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.konform.validation.ValidationBuilder.kt Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
package io.konform.validation

import io.konform.validation.internal.ArrayValidation
import io.konform.validation.internal.IterableValidation
import io.konform.validation.internal.MapValidation
import io.konform.validation.internal.OptionalValidation
import io.konform.validation.internal.RequiredValidation
import io.konform.validation.internal.ValidationBuilderImpl
import kotlin.jvm.JvmName
import kotlin.reflect.KFunction1
import kotlin.reflect.KProperty1

@DslMarker
private annotation class ValidationScope

@ValidationScope
public abstract class ValidationBuilder {
    public abstract fun build(): Validation

    public abstract fun addConstraint(
        errorMessage: String,
        vararg templateValues: String,
        test: (T) -> Boolean,
    ): Constraint

    public abstract infix fun Constraint.hint(hint: String): Constraint

    internal abstract fun  onEachIterable(
        name: String,
        prop: (T) -> Iterable,
        init: ValidationBuilder.() -> Unit,
    )

    internal abstract fun  onEachArray(
        name: String,
        prop: (T) -> Array,
        init: ValidationBuilder.() -> Unit,
    )

    internal abstract fun  onEachMap(
        name: String,
        prop: (T) -> Map,
        init: ValidationBuilder>.() -> Unit,
    )

    @JvmName("onEachIterable")
    public infix fun  KProperty1>.onEach(init: ValidationBuilder.() -> Unit): Unit = onEachIterable(name, this, init)

    @JvmName("onEachIterable")
    public infix fun  KFunction1>.onEach(init: ValidationBuilder.() -> Unit): Unit =
        onEachIterable("$name()", this, init)

    @JvmName("onEachArray")
    public infix fun  KProperty1>.onEach(init: ValidationBuilder.() -> Unit): Unit = onEachArray(name, this, init)

    @JvmName("onEachArray")
    public infix fun  KFunction1>.onEach(init: ValidationBuilder.() -> Unit): Unit = onEachArray("$name()", this, init)

    @JvmName("onEachMap")
    public infix fun  KProperty1>.onEach(init: ValidationBuilder>.() -> Unit): Unit =
        onEachMap(name, this, init)

    @JvmName("onEachMap")
    public infix fun  KFunction1>.onEach(init: ValidationBuilder>.() -> Unit): Unit =
        onEachMap("$name()", this, init)

    public operator fun  KProperty1.invoke(init: ValidationBuilder.() -> Unit): Unit = validate(name, this, init)

    public operator fun  KFunction1.invoke(init: ValidationBuilder.() -> Unit): Unit = validate("$name()", this, init)

    public infix fun  KProperty1.ifPresent(init: ValidationBuilder.() -> Unit): Unit = ifPresent(name, this, init)

    public infix fun  KFunction1.ifPresent(init: ValidationBuilder.() -> Unit): Unit = ifPresent("$name()", this, init)

    public infix fun  KProperty1.required(init: ValidationBuilder.() -> Unit): Unit = required(name, this, init)

    public infix fun  KFunction1.required(init: ValidationBuilder.() -> Unit): Unit = required("$name()", this, init)

    /**
     * Calculate a value from the input and run a validation on it.
     * @param name The name that should be reported in validation errors. Must be a valid kotlin name, optionally followed by ().
     * @param f The function for which you want to validate the result of
     * @see run
     */
    public abstract fun  validate(
        name: String,
        f: (T) -> R,
        init: ValidationBuilder.() -> Unit,
    )

    /**
     * Calculate a value from the input and run a validation on it, but only if the value is not null.
     */
    public abstract fun  ifPresent(
        name: String,
        f: (T) -> R?,
        init: ValidationBuilder.() -> Unit,
    )

    /**
     * Calculate a value from the input and run a validation on it, and give an error if the result is null.
     */
    public abstract fun  required(
        name: String,
        f: (T) -> R?,
        init: ValidationBuilder.() -> Unit,
    )

    /** Run an arbitrary other validation. */
    public abstract fun run(validation: Validation)

    public abstract val  KProperty1.has: ValidationBuilder
    public abstract val  KFunction1.has: ValidationBuilder
}

/**
 * Run a validation if the property is not-null, and allow nulls.
 */
public fun  ValidationBuilder.ifPresent(init: ValidationBuilder.() -> Unit) {
    val builder = ValidationBuilderImpl()
    init(builder)
    run(OptionalValidation(builder.build()))
}

/**
 * Run a validation on a nullable property, giving an error on nulls.
 */
public fun  ValidationBuilder.required(init: ValidationBuilder.() -> Unit) {
    val builder = ValidationBuilderImpl()
    init(builder)
    run(RequiredValidation(builder.build()))
}

@JvmName("onEachIterable")
public fun > ValidationBuilder.onEach(init: ValidationBuilder.() -> Unit) {
    val builder = ValidationBuilderImpl()
    init(builder)
    @Suppress("UNCHECKED_CAST")
    run(IterableValidation(builder.build()) as Validation)
}

@JvmName("onEachArray")
public fun  ValidationBuilder>.onEach(init: ValidationBuilder.() -> Unit) {
    val builder = ValidationBuilderImpl()
    init(builder)
    run(ArrayValidation(builder.build()))
}

@JvmName("onEachMap")
public fun > ValidationBuilder.onEach(init: ValidationBuilder>.() -> Unit) {
    val builder = ValidationBuilderImpl>()
    init(builder)
    @Suppress("UNCHECKED_CAST")
    run(MapValidation(builder.build()) as Validation)
}