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

com.ancientlightstudios.quarkus.kotlin.openapi.MaybeValidation.kt Maven / Gradle / Ivy

package com.ancientlightstudios.quarkus.kotlin.openapi

import com.fasterxml.jackson.databind.JsonNode

@Suppress("unused")
fun  Maybe.validate(block: DefaultValidator.(T) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = DefaultValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validate
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
fun Maybe.validateString(block: StringValidator.(String) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = StringValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateString
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

// TODO: name should be validateByteArray, but we can't determine the correct name right now in the ValidationStatementEmitter
@Suppress("unused")
@JvmName("validateByteArray")
fun Maybe.validateString(block: ByteArrayValidator.(ByteArray) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = ByteArrayValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateString
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
@JvmName("validateNumber")
fun  Maybe.validateNumber(block: NumberValidator.(T) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = NumberValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateNumber
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
@JvmName("validateULongNumber")
fun Maybe.validateNumber(block: NumberValidator.(ULong) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = NumberValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateNumber
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
@JvmName("validateUIntNumber")
fun Maybe.validateNumber(block: NumberValidator.(UInt) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = NumberValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateNumber
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
@JvmName("validateUShortNumber")
fun Maybe.validateNumber(block: NumberValidator.(UShort) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = NumberValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateNumber
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
@JvmName("validateUByteNumber")
fun Maybe.validateNumber(block: NumberValidator.(UByte) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = NumberValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateNumber
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
fun  Maybe?>.validateList(block: ListValidator.(List) -> Unit): Maybe?> =
    onNotNull {
        try {
            val errors = ListValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateList
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
fun  Maybe?>.validateProperties(block: PropertiesValidator.(Map) -> Unit): Maybe?> =
    onNotNull {
        try {
            val errors = PropertiesValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateProperties
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
@JvmName("validateObjectWithPropertiesContainer")
fun  Maybe.validateProperties(block: PropertiesValidator.(I) -> Unit): Maybe =
    onNotNull {
        try {
            val errors = PropertiesValidator(context).apply { this.block(value) }.validationErrors
            if (errors.isEmpty()) {
                this@validateProperties
            } else {
                failure(errors)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
fun  Maybe?>.mapItems(block: (Maybe.Success) -> Maybe): Maybe?> =
    onNotNull {
        try {
            val validated = mutableListOf()
            val errors = mutableListOf()
            value.forEachIndexed { index, item ->
                when (val validatedItem = block(Maybe.Success("$context[$index]", item))) {
                    is Maybe.Failure -> errors.addAll(validatedItem.errors)
                    is Maybe.Success -> validated.add(validatedItem.value)
                }
            }

            if (errors.isNotEmpty()) {
                failure(errors)
            } else {
                success(validated)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }

@Suppress("unused")
fun  Maybe.propertiesAsMap(vararg ignoredProperties: String, block: (Maybe.Success) -> Maybe): Maybe?> =
    onNotNull {
        try {
            val map = mutableMapOf()
            val errors = mutableListOf()
            
            val names = value.fieldNames().asSequence().toList().minus(ignoredProperties.toSet())
            names.forEach {
                when (val validatedValue = block(Maybe.Success("$context.$it", value[it]))) {
                    is Maybe.Failure -> errors.addAll(validatedValue.errors)
                    is Maybe.Success -> map[it] = validatedValue.value
                }
            }

            if (errors.isNotEmpty()) {
                failure(errors)
            } else {
                success(map)
            }
        } catch (_: Exception) {
            failure(ValidationError("is not a valid value", context, ErrorKind.Unknown))
        }
    }


/**
 * checks that the value of the maybe is not null
 * @return the given maybe or a [Maybe.Failure] if the value was null
 */
@Suppress("unused")
fun  Maybe.required(): Maybe =
    onSuccess {
        if (value != null) {
            @Suppress("UNCHECKED_CAST")
            this as Maybe
        } else {
            failure(ValidationError("is required", context, ErrorKind.Missing))
        }
    }

/**
 * replaces a null value with the given value
 * @return the given maybe or a new [Maybe.Success] if the value was null
 */
@Suppress("unused")
fun  Maybe.default(block: () -> T): Maybe =
    onSuccess {
        if (value == null) {
            success(block())
        } else {
            this
        }
    }

/**
 * executes the given block if this maybe has a value which is not null.
 */
@Suppress("unused")
inline fun  Maybe.onNotNull(crossinline block: Maybe.Success.() -> Maybe): Maybe =
    onSuccess {
        if (value != null) {
            @Suppress("UNCHECKED_CAST")
            (this as Maybe.Success).block()
        } else {
            @Suppress("UNCHECKED_CAST")
            this as Maybe
        }
    }