From 05d50b7fec517de0ed7ab76cf7f2085f53fedbf9 Mon Sep 17 00:00:00 2001 From: Michael Bull Date: Sat, 2 Mar 2024 16:36:56 +0000 Subject: [PATCH] Facilitate mapping to arbitrary types in and/or functions Closes #95 --- .../com/github/michaelbull/result/And.kt | 4 ++-- .../com/github/michaelbull/result/Or.kt | 6 ++--- .../com/github/michaelbull/result/ZipTest.kt | 24 +++++++++++-------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/And.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/And.kt index e4881e9..23efe49 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/And.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/And.kt @@ -8,7 +8,7 @@ import kotlin.contracts.contract * * - Rust: [Result.and](https://doc.rust-lang.org/std/result/enum.Result.html#method.and) */ -public infix fun Result.and(result: Result): Result { +public infix fun Result.and(result: Result): Result { return when (this) { is Ok -> result is Err -> this @@ -16,7 +16,7 @@ public infix fun Result.and(result: Result): Result { } @Deprecated("Use andThen instead", ReplaceWith("andThen { result() }")) -public inline infix fun Result.and(result: () -> Result): Result { +public inline infix fun Result.and(result: () -> Result): Result { contract { callsInPlace(result, InvocationKind.AT_MOST_ONCE) } diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt index 6469b8f..d74900a 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt @@ -8,7 +8,7 @@ import kotlin.contracts.contract * * - Rust: [Result.or](https://doc.rust-lang.org/std/result/enum.Result.html#method.or) */ -public infix fun Result.or(result: Result): Result { +public infix fun Result.or(result: Result): Result { return when (this) { is Ok -> this is Err -> result @@ -16,7 +16,7 @@ public infix fun Result.or(result: Result): Result { } @Deprecated("Use orElse instead", ReplaceWith("orElse { result() }")) -public inline infix fun Result.or(result: () -> Result): Result { +public inline infix fun Result.or(result: () -> Result): Result { contract { callsInPlace(result, InvocationKind.AT_MOST_ONCE) } @@ -30,7 +30,7 @@ public inline infix fun Result.or(result: () -> Result): Resu * * - Rust: [Result.or_else](https://doc.rust-lang.org/std/result/enum.Result.html#method.or_else) */ -public inline infix fun Result.orElse(transform: (E) -> Result): Result { +public inline infix fun Result.orElse(transform: (E) -> Result): Result { contract { callsInPlace(transform, InvocationKind.AT_MOST_ONCE) } diff --git a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ZipTest.kt b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ZipTest.kt index b1ac10d..8273fee 100644 --- a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ZipTest.kt +++ b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ZipTest.kt @@ -3,6 +3,10 @@ package com.github.michaelbull.result import kotlin.test.Test import kotlin.test.assertEquals +private inline fun produce(number: Int, error: String): Result { + return Ok(number).and(Err(error)) +} + class ZipTest { data class ZipData3(val a: String, val b: Int, val c: Boolean) @@ -31,7 +35,7 @@ class ZipTest { fun returnsErrIfOneOfTwoErr() { val result = zip( { Ok(10) }, - { Ok(20).and(Err("hello")) }, + { produce(20, "hello") }, Int::plus ) @@ -46,8 +50,8 @@ class ZipTest { @Test fun returnsFirstErrIfBothErr() { val result = zip( - { Ok(10).and(Err("foo")) }, - { Ok(20).and(Err("bar")) }, + { produce(10, "foo") }, + { produce(20, "bar") }, Int::plus ) @@ -225,11 +229,11 @@ class ZipTest { @Test fun returnsAllErrsIfAllErr() { val result = zipOrAccumulate( - { Ok(10).and(Err("error one")) }, - { Ok(20).and(Err("error two")) }, - { Ok(30).and(Err("error three")) }, - { Ok(40).and(Err("error four")) }, - { Ok(50).and(Err("error five")) }, + { produce(10, "error one") }, + { produce(20, "error two") }, + { produce(30, "error three") }, + { produce(40, "error four") }, + { produce(50, "error five") }, ) { a, b, c, d, e -> a + b + c + d + e } @@ -252,7 +256,7 @@ class ZipTest { fun returnsOneErrsIfOneOfErr() { val result = zipOrAccumulate( { Ok(10) }, - { Ok(20).and(Err("only error")) }, + { produce(20, "only error") }, { Ok(30) }, { Ok(40) }, { Ok(50) }, @@ -263,7 +267,7 @@ class ZipTest { result as Err assertEquals( - expected = listOf("only error",), + expected = listOf("only error"), actual = result.error, ) }