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

commonMain.schemas.util.SchemaRestrictions.kt Maven / Gradle / Ivy

There is a newer version: 0.23.0
Show newest version
@file:JvmName("SchemaRestrictions")

package io.kform.schemas.util

import io.kform.Validation
import io.kform.datatypes.File
import io.kform.validations.*
import kotlin.jvm.JvmName

/** Builds the common restrictions of a schema, given its validations. */
public fun  commonRestrictions(validations: Iterable>): Map =
    buildMap {
        if (validations.any { it is Required }) {
            put("required", true)
        }

        val allowedValuesSets =
            validations.filterIsInstance>().map { it.allowedValues } +
                validations.filterIsInstance>().map { setOf(it.requiredValue) }
        if (allowedValuesSets.isNotEmpty()) {
            put(
                "allowedValues",
                allowedValuesSets
                    .reduce { intersectedAllowedValues, allowedValues ->
                        intersectedAllowedValues intersect allowedValues
                    }
                    .toTypedArray()
            )
        }

        val disallowedValues =
            validations.filterIsInstance>().flatMapTo(mutableSetOf()) {
                it.disallowedValues
            } + validations.filterIsInstance>().map { it.forbiddenValue }
        if (disallowedValues.isNotEmpty()) {
            put("disallowedValues", disallowedValues.toTypedArray())
        }
    }

/** Builds the comparable bounds restrictions of a schema, given its validations. */
public fun > comparableBoundsRestrictions(
    validations: Iterable>,
    typeMin: T? = null,
    typeMax: T? = null
): Map = buildMap {
    val validationMin = validations.filterIsInstance>().maxOfOrNull { it.min }
    val min =
        if (typeMin != null && validationMin != null) maxOf(typeMin, validationMin)
        else typeMin ?: validationMin
    if (min != null) {
        put("min", min)
    }

    val validationMax = validations.filterIsInstance>().minOfOrNull { it.max }
    val max =
        if (typeMax != null && validationMax != null) minOf(typeMax, validationMax)
        else typeMax ?: validationMax
    if (max != null) {
        put("max", max)
    }

    val exclusiveMin =
        validations.filterIsInstance>().maxOfOrNull { it.exclusiveMin }
    if (exclusiveMin != null) {
        put("exclusiveMin", exclusiveMin)
    }

    val exclusiveMax =
        validations.filterIsInstance>().minOfOrNull { it.exclusiveMax }
    if (exclusiveMax != null) {
        put("exclusiveMax", exclusiveMax)
    }
}

/** Builds the size bounds restrictions of a schema, given its validations. */
public fun sizeBoundsRestrictions(validations: Iterable>): Map =
    buildMap {
        val minSize =
            (validations.filterIsInstance() + validations.filterIsInstance())
                .maxOfOrNull { if (it is MinSize) it.minSize else (it as Size).requiredSize }
        if (minSize != null) {
            put("minSize", minSize)
        }

        val maxSize =
            (validations.filterIsInstance() + validations.filterIsInstance())
                .minOfOrNull { if (it is MaxSize) it.maxSize else (it as Size).requiredSize }
        if (maxSize != null) {
            put("maxSize", maxSize)
        }
    }

/** Builds the size length restrictions of a schema, given its validations. */
public fun  lengthBoundsRestrictions(
    validations: Iterable>
): Map = buildMap {
    val minLength =
        (validations.filterIsInstance() + validations.filterIsInstance())
            .maxOfOrNull { if (it is MinLength) it.minLength else (it as Length).requiredLength }
    if (minLength != null) {
        put("minLength", minLength)
    }

    val maxLength =
        (validations.filterIsInstance() + validations.filterIsInstance())
            .minOfOrNull { if (it is MaxLength) it.maxLength else (it as Length).requiredLength }
    if (maxLength != null) {
        put("maxLength", maxLength)
    }
}

/** Builds the pattern restrictions of a schema, given its validations. */
public fun patternRestrictions(validations: Iterable>): Map =
    buildMap {
        val matchesValidations = validations.filterIsInstance()
        if (matchesValidations.isNotEmpty()) {
            put(
                "pattern",
                if (matchesValidations.size == 1) matchesValidations.first().regex.pattern
                else matchesValidations.joinToString("|") { "(${it.regex.pattern})" }
            )
        }
    }

/** Builds the accepted file types restrictions of a schema, given its validations. */
public fun acceptedFileTypesRestrictions(
    validations: Iterable>
): Map = buildMap {
    val acceptedFileTypesValidations = validations.filterIsInstance()
    if (acceptedFileTypesValidations.isNotEmpty()) {
        // FIXME: This is incorrect, if one [Accepts] validation allows image/* and another
        //  image/jpeg, the intersection should be image/jpeg, rather than the empty set
        put(
            "acceptedFileTypes",
            acceptedFileTypesValidations
                .map { it.acceptedFileTypes }
                .reduce { intersectedAcceptedFileTypes, acceptedFileTypes ->
                    intersectedAcceptedFileTypes intersect acceptedFileTypes
                }
                .toTypedArray()
        )
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy