diff --git a/libraries/core/src/main/java/com/raxdenstudios/commons/core/ext/AnswerExtension.kt b/libraries/core/src/main/java/com/raxdenstudios/commons/core/ext/AnswerExtension.kt index 864f2c11..edce03a8 100644 --- a/libraries/core/src/main/java/com/raxdenstudios/commons/core/ext/AnswerExtension.kt +++ b/libraries/core/src/main/java/com/raxdenstudios/commons/core/ext/AnswerExtension.kt @@ -70,3 +70,15 @@ fun Answer.onFailure( is Answer.Failure -> also { function(value) } is Answer.Success -> this } + +@Suppress("UNCHECKED_CAST") +fun Answer.combine( + other: Answer, + transform: (T1, T2) -> R +): Answer = when (this) { + is Answer.Failure -> this as Answer + is Answer.Success -> when (other) { + is Answer.Failure -> other as Answer + is Answer.Success -> Answer.Success(transform(this.value, other.value)) + } +} diff --git a/libraries/core/src/test/java/com/raxdenstudios/commons/core/ext/AnswerExtensionTest.kt b/libraries/core/src/test/java/com/raxdenstudios/commons/core/ext/AnswerExtensionTest.kt index 7abcf5c9..81a3bafe 100644 --- a/libraries/core/src/test/java/com/raxdenstudios/commons/core/ext/AnswerExtensionTest.kt +++ b/libraries/core/src/test/java/com/raxdenstudios/commons/core/ext/AnswerExtensionTest.kt @@ -217,4 +217,47 @@ internal class AnswerExtensionTest { assertThat(result).isEqualTo(Answer.Failure("originalValue")) } + @Test + fun `use combine when both are success`() { + val answer1 = Answer.Success(5) + val answer2 = Answer.Success(10) + + val result = answer1.combine(answer2) { a, b -> a + b } + + assertTrue(result.isSuccess) + assertThat(result).isEqualTo(Answer.Success(15)) + } + + @Test + fun `use combine when first is failure`() { + val answer1: Answer = Answer.Failure("error1") + val answer2 = Answer.Success(10) + + val result = answer1.combine(answer2) { a, b -> a + b } + + assertTrue(result.isFailure) + assertThat(result).isEqualTo(Answer.Failure("error1")) + } + + @Test + fun `use combine when second is failure`() { + val answer1 = Answer.Success(5) + val answer2: Answer = Answer.Failure("error2") + + val result = answer1.combine(answer2) { a, b -> a + b } + + assertTrue(result.isFailure) + assertThat(result).isEqualTo(Answer.Failure("error2")) + } + + @Test + fun `use combine when both are failure`() { + val answer1: Answer = Answer.Failure("error1") + val answer2: Answer = Answer.Failure("error2") + + val result = answer1.combine(answer2) { a, b -> a + b } + + assertTrue(result.isFailure) + assertThat(result).isEqualTo(Answer.Failure("error1")) + } } diff --git a/libraries/coroutines/src/main/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtension.kt b/libraries/coroutines/src/main/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtension.kt index fb94571a..398c1549 100644 --- a/libraries/coroutines/src/main/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtension.kt +++ b/libraries/coroutines/src/main/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtension.kt @@ -69,5 +69,17 @@ fun Flow>.thenFailure( map { result -> result.coThenFailure { function(it) } } fun Flow.toAnswer() = - map { stations -> Answer.Success(stations) } + map { data -> Answer.Success(data) } .catch { error -> Answer.Failure(error) } + +@Suppress("UNCHECKED_CAST") +suspend fun Answer.coCombine( + other: Answer, + transform: suspend (T1, T2) -> R +): Answer = when (this) { + is Answer.Failure -> this as Answer + is Answer.Success -> when (other) { + is Answer.Failure -> other as Answer + is Answer.Success -> Answer.Success(transform(this.value, other.value)) + } +} diff --git a/libraries/coroutines/src/test/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtensionTest.kt b/libraries/coroutines/src/test/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtensionTest.kt index 1930c79f..44e5df6d 100644 --- a/libraries/coroutines/src/test/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtensionTest.kt +++ b/libraries/coroutines/src/test/java/com/raxdenstudios/commons/coroutines/ext/AnswerExtensionTest.kt @@ -224,4 +224,48 @@ internal class AnswerExtensionTest { awaitComplete() } } + + @Test + fun `use coCombine when both are success`() = runTest { + val answer1 = Answer.Success(5) + val answer2 = Answer.Success(10) + + val result = answer1.coCombine(answer2) { a, b -> a + b } + + assertTrue(result.isSuccess) + assertThat(result).isEqualTo(Answer.Success(15)) + } + + @Test + fun `use coCombine when first is failure`() = runTest { + val answer1: Answer = Answer.Failure("error1") + val answer2 = Answer.Success(10) + + val result = answer1.coCombine(answer2) { a, b -> a + b } + + assertTrue(result.isFailure) + assertThat(result).isEqualTo(Answer.Failure("error1")) + } + + @Test + fun `use coCombine when second is failure`() = runTest { + val answer1 = Answer.Success(5) + val answer2: Answer = Answer.Failure("error2") + + val result = answer1.coCombine(answer2) { a, b -> a + b } + + assertTrue(result.isFailure) + assertThat(result).isEqualTo(Answer.Failure("error2")) + } + + @Test + fun `use coCombine when both are failure`() = runTest { + val answer1: Answer = Answer.Failure("error1") + val answer2: Answer = Answer.Failure("error2") + + val result = answer1.coCombine(answer2) { a, b -> a + b } + + assertTrue(result.isFailure) + assertThat(result).isEqualTo(Answer.Failure("error1")) + } } diff --git a/libraries/permissions/src/main/java/com/raxdenstudios/commons/permissions/model/Permission.kt b/libraries/permissions/src/main/java/com/raxdenstudios/commons/permissions/model/Permission.kt index 22afee85..52a20fbd 100644 --- a/libraries/permissions/src/main/java/com/raxdenstudios/commons/permissions/model/Permission.kt +++ b/libraries/permissions/src/main/java/com/raxdenstudios/commons/permissions/model/Permission.kt @@ -1,6 +1,8 @@ package com.raxdenstudios.commons.permissions.model import android.Manifest +import android.os.Build +import androidx.annotation.RequiresApi sealed class Permission( val value: String, @@ -41,6 +43,11 @@ sealed class Permission( value = Manifest.permission.WRITE_EXTERNAL_STORAGE, ) + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + data object PostNotifications : Permission( + value = Manifest.permission.POST_NOTIFICATIONS, + ) + data class Other( val permission: String ) : Permission( @@ -55,6 +62,7 @@ sealed class Permission( * @param value * @return */ + @RequiresApi(Build.VERSION_CODES.TIRAMISU) fun fromValue(value: String): Permission = when (value) { Manifest.permission.CAMERA -> Camera Manifest.permission.ACCESS_FINE_LOCATION -> AccessFineLocation @@ -65,6 +73,7 @@ sealed class Permission( Manifest.permission.CALL_PHONE -> CallPhone Manifest.permission.READ_EXTERNAL_STORAGE -> ReadExternalStorage Manifest.permission.WRITE_EXTERNAL_STORAGE -> WriteExternalStorage + Manifest.permission.POST_NOTIFICATIONS -> PostNotifications else -> Other(value) } }