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

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

package com.ancientlightstudios.quarkus.kotlin.openapi

import com.ancientlightstudios.quarkus.kotlin.openapi.Maybe.Failure
import com.ancientlightstudios.quarkus.kotlin.openapi.Maybe.Success

sealed class Maybe(val context: String) {
    class Success(context: String, val value: T) : Maybe(context) {
        override fun  onSuccess(block: Success.() -> Maybe): Maybe = block(this)

        fun  success(value: O) = Success(context, value)
        fun  failure(error: ValidationError) = Failure(context, error)
        fun  failure(errors: List) = Failure(context, errors)
    }

    class Failure(context: String, val errors: List) : Maybe(context) {
        constructor(context: String, error: ValidationError) : this(context, listOf(error))

        @Suppress("UNCHECKED_CAST")
        override fun  onSuccess(block: Success.() -> Maybe): Maybe = this as Maybe
    }

    /**
     * executes the given block and returns its result if this maybe is a [Success] or just returns the [Failure]
     */
    abstract fun  onSuccess(block: Success.() -> Maybe): Maybe

}

/**
 * combines the given maybes. Returns a [Success] with the result of the builder if all given maybes are
 * [Success] too, a [Failure] otherwise.
 */
@Suppress("unused")
fun  maybeAllOf(context: String, vararg maybes: Maybe<*>, builder: () -> T): Maybe {
    val errors = maybes.filterIsInstance>().flatMap { it.errors }
    return if (errors.isEmpty()) {
        Success(context, builder())
    } else {
        Failure(context, errors)
    }
}

/**
 * combines the given maybes. Returns a [Success] with the result of the builder if at least one given maybe is
 * a [Success], a [Failure] otherwise.
 */
@Suppress("unused")
fun  maybeAnyOf(context: String, vararg maybes: Maybe<*>, builder: () -> T): Maybe {
    return if (maybes.any { it is Success }) {
        Success(context, builder())
    } else {
        val errors = maybes.filterIsInstance>().flatMap { it.errors }
        Failure(context, errors)
    }
}

/**
 * combines the given maybes. Returns a [Success] with the result of the builder if exactly one given maybe
 * is a [Success], a [Failure] otherwise.
 */
@Suppress("unused")
fun  maybeOneOf(context: String, vararg maybes: Maybe<*>, builder: () -> T): Maybe {
    val count = maybes.count { it is Success }
    return if (count == 1) {
        Success(context, builder())
    } else if (count > 1) {
        Failure(context, ValidationError("is ambiguous", context))
    } else {
        val errors = maybes.filterIsInstance>().flatMap { it.errors }
        Failure(context, errors)
    }
}

/**
 * executes the given block and returns its result if this maybe is a [Success]. Returns a [Failure] if an
 * exception occurred or this maybe already is a [Failure]
 */
@Suppress("unused")
inline fun  Maybe.map(
    validationMessage: String = "is not a valid value",
    crossinline block: (I?) -> O?
): Maybe =
    onSuccess {
        try {
            success(block(value))
        } catch (e: Exception) {
            failure(ValidationError(validationMessage, context))
        }
    }

/**
 * executes the given block and returns its result if this maybe is a [Success] and has a non-null value. Returns a
 * [Failure] if an exception occurred or this maybe already is a [Failure]
 */
@Suppress("unused")
inline fun  Maybe.mapNotNull(
    validationMessage: String = "is not a valid value",
    crossinline block: (I) -> O?
): Maybe =
    onNotNull {
        try {
            success(block(value))
        } catch (_: Exception) {
            failure(ValidationError(validationMessage, context))
        }
    }

/**
 * executes the given block if this maybe is a [Failure] or returns the value of the [Success]
 */
@Suppress("unused")
inline fun  Maybe.validOrElse(block: (List) -> Nothing): T {
    if (this is Failure) {
        block(errors)
    }
    return (this as Success).value
}

inline fun  Maybe.doOnSuccess(block: (T) -> Unit) {
    if (this is Success) {
        block(value)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy