Skip to content
Michael Bull edited this page Mar 16, 2024 · 24 revisions

Mappings from Rust's Result type to kotlin-result.


<V, E> Result<V, E>.and(result: Result<V, E>): Result<V, E>

Returns result if this Result<V, E> is Ok, otherwise returns the Err value of this.

val result = Ok(2).and(Err("late error"))
// result = Err("late error")

val result = Err("early error").and(Ok("foo"))
// result = Err("early error")

val result = Err("not a 2").and(Err("late error"))
// result = Err("not a 2")

val result = Ok(2).and(Ok("different result type"))
// result = Ok("different result type")

<V, E, U> Result<V, E>.andThen(transform: (V) -> Result<U, E>): Result<U, E>

Calls transform if this Result<V, E> is Ok, otherwise returns the Err value of this.

This function can be used for control flow based on Result values.

fun sq(x: Int) = Ok(x * x)
fun err(x: Int) = Err(x)
    
val result = Ok(2).andThen(::sq).andThen(::sq)
// result = Ok(16)
    
val result = Ok(2).andThen(::sq).andThen(::err)
// result = Err(4)
    
val result = Ok(2).andThen(::err).andThen(::sq)
// result = Err(2)
    
val result = Err(3).andThen(::sq).andThen(::sq)
// result = Err(3)

<V, E> Result<V, E>.getError(): E?

Converts from Result<V, E> to E?.

val value = Ok(230).getError()
val error = Err("example").getError()
// value = null
// error = "example"

<V, E> Result<V, E>.expect(message: () -> Any): V

Unwraps a result, yielding the content of an Ok.

Throws an UnwrapException if the value is an Err, with a message including the passed message, and the content of the Err.

Err(1994).expect { "the year should be" }
// throws UnwrapException("the year should be 1994")

<V, E> Result<V, E>.expectError(message: () -> Any): E

Unwraps a Result<V, E>, yielding the content of an Err.

Throws an UnwrapException if the value is an Ok, with a message including the passed message, and the content of the Ok.

Ok(2010).expectError { "the year should be" }
// throws UnwrapException("the year should be 2010")

<V, E> Result<Result<V, E>, E>.flatten(): Result<V, E>

Converts from Result<Result<V, E>, E> to Result<V, E>.

val result = Ok(Ok("hello")).flatten()
// result = Ok("hello")

val result = Ok(Err(6)).flatten()
// result = Err(6)

val result = Err(6).flatten()
// result = Err(6)

Flattening only removes one level of nesting at a time:

val result = Ok(Ok(Ok("hello"))).flatten()
// result = Ok(Ok("hello"))

val result = Ok(Ok(Ok("hello"))).flatten().flatten()
// result = Ok("hello")

<V, E> Result<V, E>.onSuccess(action: (V) -> Unit): Result<V, E>

Calls the provided closure with a reference to the contained value (if Ok).

fun tryParse(): Result<Int, ParseError>

val result: Int = "4"
    .tryParse()
    .onSuccess { x -> println("original $x") }
    .map { x -> x.toDouble().pow(3) }
    .expect { "failed to parse number" }

Result<V, E>.onFailure(action: (E) -> Unit): Result<V, E>

Calls the provided closure with a reference to the contained error (if Err)

fun readToString(file: String): Result<String, IoError>

val result = readToString("address.txt")
    .onFailure { e -> println("failed to read file: $e") }

Returns true if the result is Err.

val result = Err(500)
if (result.isErr) {
    println("Result is not ok")
}

Returns true if the result is Ok.

val result = Ok(500)
if (result.isOk) {
    println("Result is ok")
}

<V, E> Result<V, E>.iterator(): Iterator<V>

Returns an Iterator over the possibly contained value.

The iterator yields one value if the result is Ok, otherwise throws NoSuchElementException.

val iterator = Ok("hello").iterator()
// iterator.hasNext() = true
// iterator.next() = "hello"

<V, E> Result<V, E>.mutableIterator(): MutableIterator<V>

Returns a MutableIterator over the possibly contained value.

The iterator yields one value if the result is Ok, otherwise throws NoSuchElementException.

val iterator = Ok("hello").mutableIterator()
iterator.remove()
// iterator.hasNext() = false
// iterator.next() throws NoSuchElementException

<V, E, U> Result<V, E>.map(transform: (V) -> U): Result<U, E>

Maps a Result<V, E> to Result<U, E> by applying a function to a contained Ok value, leaving an Err value untouched.

This function can be used to compose the results of two functions.

val result = Ok(10).map { it + 20 }
// result = Ok(30)

<V, E, F> Result<V, E>.mapError(transform: (E) -> F): Result<V, F>

Maps a Result<V, E> to Result<V, F> by applying a function to a contained Err value, leaving an Ok value untouched.

This function can be used to pass through a successful result while handling an error.

val result = Ok(55).andThen { Err(100) }.mapError { it * 5 }
// result = Err(500)

<V, E, U> Result<V, E>.mapOr(default: U, transform: (V) -> U): U

Applies a function to the contained value (if Ok), or returns the provided default (if Err).

Arguments passed to mapOr are eagerly evaluated; if you are passing the result of a function call, it is recommended to use mapOrElse, which is lazily evaluated.

val result = Ok("foo").mapOr(42, String::length)
// result = 3

val result = Err("foo").mapOr(42, String::length)
// result = 42

<V, E, U> Result<V, E>.mapOrElse(default: (E) -> U, transform: (V) -> U): U

Maps a Result<V, E> to U by applying a function to a contained Ok value, or a fallback function to a contained Err value.

This function can be used to unpack a successful result while handling an error.

val k = 21
val result = Ok("foo").mapOrElse({ k * 2 }, String::length)
// result = 3

val k = 21
val result = Err("foo").mapOrElse({ k * 2 }, String::length)
// result = 42

<V, E> Result<V, E>.get(): V?

Converts from Result<V, E> to V?.

val value = Ok(230).get()
val error = Err("example").get()
// value = 230
// error = null

<V, E> Result<V, E>.or(result: Result<V, E>): Result<V, E>

Returns result if this Result<V, E> is Err, otherwise returns the Ok value of this.

val result = Ok(2).or(Err("late error"))
// result = Ok(2)

val result = Err("early error").or(Ok(2))
// result = Ok(2)

val result = Err("not a 2").or(Err("late error"))
// result = Err("late error")
    
val result = Ok(2).or(Ok(100))
// result = Ok(2)

<V, E> Result<V, E>.orElse(transform: (E) -> Result<V, E>): Result<V, E>

Calls transform if the result is Err, otherwise returns the Ok value of this.

This function can be used for control flow based on result values.

fun sq(x: Int) = Ok(x * x)
fun err(x: Int) = Err(x)

val result = Ok(2).orElse(::sq).orElse(::sq)
// result = Ok(2)

val result = Ok(2).orElse(::err).orElse(::sq)
// result = Ok(2)

val result = Err(3).orElse(::sq).orElse(::err)
// result = Ok(9)

val result = Err(3).orElse(::err).orElse(::err)
// result = Err(3)

<V, E> Result<V, E>.unwrap(): V

Unwraps a result, yielding the content of an Ok.

Throws an UnwrapException if the value is an Err, with a message provided by the Err's value.

Err(5000).unwrap()
// throws UnwrapException("called Result.wrap on an Err value 5000")

<V, E> Result<V, E>.unwrapError(): E

Unwraps a result, yielding the content of an Err.

Throws an UnwrapException if the value is an Ok, with a custom message provided by the Ok's value.

val error = Err("example").unwrapError()
// error = "example"

<V, E> Result<V, E>.getOr(default: V): V

Unwraps a Result<V, E>, yielding the content of an Ok. Else, it returns default.

Arguments passed to getOr are eagerly evaluated; if you are passing the result of a function call, it is recommended to use getOrElse, which is lazily evaluated.

val value = Err("error").getOr("default")
// value = default

<V, E> Result<V, E>.getOrElse(transform: (E) -> V): V

Returns the contained Ok value or computes it from a function.

val value = Err("hello").getOrElse { "world" }
// value = "world"