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

com.natpryce.result.kt Maven / Gradle / Ivy

package com.natpryce

/**
 * A result of a computation that can succeed or fail.
 */
sealed class Result
data class Ok(val value: T) : Result()
data class Err(val reason: E) : Result()

/**
 * Call a function and wrap the result in a Result, catching any Exception and returning it as Err value.
 */
inline fun  resultFrom(block: () -> T): Result =
    try {
        Ok(block())
    }
    catch (x: Exception) {
        Err(x)
    }
    catch (t: Throwable) {
        throw t
    }

/**
 * Map a function over the _value_ of a successful Result.
 */
inline fun  Result.map(f: (T) -> U): Result = when (this) {
    is Ok -> Ok(f(value))
    is Err -> this
}

/**
 * Flat-map a function over the _value_ of a successful Result.
 */
inline fun  Result.flatMap(f: (T) -> Result): Result = when (this) {
    is Ok -> f(value)
    is Err -> this
}

/**
 * Map a function over the _reason_ of an unsuccessful Result.
 */
inline fun  Result.mapError(f: (E) -> F): Result = when (this) {
    is Ok -> this
    is Err -> Err(f(reason))
}

/**
 * Unwrap a Result in which both the success and error values have the same type, returning a plain value.
 */
fun  Result.get() = when (this) {
    is Ok -> value
    is Err -> reason
}

/**
 * Unwrap a Result, by returning the success value or calling _block_ on error to abort from the current function.
 */
inline fun  Result.onError(block: (Err) -> Nothing): T = when (this) {
    is Ok -> value
    is Err -> block(this)
}

/**
 * Perform a side effect with the success value.
 */
inline fun  Result.peek(f: (T) -> Unit) =
    apply { if (this is Ok) f(value) }

/**
 * Perform a side effect with the error reason.
 */
inline fun  Result.peekError(f: (E) -> Unit) =
    apply { if (this is Err) f(reason) }


/*
 * Translate between the Result and Nullable/Optional/Maybe monads
 */

/**
 * Convert a nullable value to a Result, using the result of the errorSupplier as the error reason if the value is null.
 */
inline fun  T?.asResultOr(errorSupplier: () -> E) =
    if (this != null) Ok(this) else Err(errorSupplier())

/**
 * Returns the success value, or null if the Result is an error.
 */
fun  Result.valueOrNull() = when (this) {
    is Ok -> value
    is Err -> null
}

/**
 * Returns the error reason, or null if the Result is a success.
 */
fun  Result.errorOrNull() = when (this) {
    is Ok -> null
    is Err -> reason
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy