Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.skydoves.sandwich

import com.skydoves.sandwich.ErrorEnvelopeMapper.map
import com.skydoves.sandwich.retrofit.responseOf
import com.skydoves.sandwich.retrofit.statusCode
import kotlinx.coroutines.flow.first
Expand Down Expand Up @@ -925,7 +924,7 @@ internal class ResponseTransformerTest : ApiAbstract<DisneyService>() {
fun validateOnSuccessPassTest() {
val response = Response.success("foo")
val apiResponse = ApiResponse.responseOf { response }
val validated = apiResponse.validate({ it.length > 2 }) { "Too short" }
val validated = apiResponse.validate({ it.length > 2 }, errorMessage = "Too short")

assertThat(validated.getOrNull(), `is`("foo"))
}
Expand All @@ -934,15 +933,15 @@ internal class ResponseTransformerTest : ApiAbstract<DisneyService>() {
fun validateOnSuccessFailTest() {
val response = Response.success("fo")
val apiResponse = ApiResponse.responseOf { response }
val validated = apiResponse.validate({ it.length > 2 }) { "Too short" }
val validated = apiResponse.validate({ it.length > 2 }, errorMessage = "Too short")

assertThat(validated is ApiResponse.Failure.Error, `is`(true))
}

@Test
fun validateOnFailureTest() {
val apiResponse = ApiResponse.exception(Throwable("error"))
val validated = apiResponse.validate({ true }) { "Error" }
val validated = apiResponse.validate({ true }, "Error")

assertThat(validated is ApiResponse.Failure.Exception, `is`(true))
}
Expand All @@ -969,7 +968,7 @@ internal class ResponseTransformerTest : ApiAbstract<DisneyService>() {
fun requireNotNullOnSuccessWithValueTest() {
val response = Response.success("foo" to "bar")
val apiResponse = ApiResponse.responseOf { response }
val required = apiResponse.requireNotNull({ it.first }) { "Value is null" }
val required = apiResponse.requireNotNull({ it.first }, "Value is null")

assertThat(required.getOrNull(), `is`("foo"))
}
Expand All @@ -978,15 +977,15 @@ internal class ResponseTransformerTest : ApiAbstract<DisneyService>() {
fun requireNotNullOnSuccessWithNullTest() {
val response = Response.success("foo" to null as String?)
val apiResponse = ApiResponse.responseOf { response }
val required = apiResponse.requireNotNull({ it.second }) { "Value is null" }
val required = apiResponse.requireNotNull({ it.second }, "Value is null")

assertThat(required is ApiResponse.Failure.Error, `is`(true))
}

@Test
fun requireNotNullOnFailureTest() {
val apiResponse = ApiResponse.exception(Throwable("error"))
val required = apiResponse.requireNotNull({ it }) { "Value is null" }
val required = apiResponse.requireNotNull({ it }, errorMessage = "Value is null")

assertThat(required is ApiResponse.Failure.Exception, `is`(true))
}
Expand Down Expand Up @@ -1469,7 +1468,9 @@ internal class ResponseTransformerTest : ApiAbstract<DisneyService>() {
onError = {},
onException = {
// This block should never be called
throw AssertionError("onException block should not be called for CancellationException")
throw AssertionError(
"onException block should not be called for CancellationException",
)
},
)
}
Expand Down
8 changes: 4 additions & 4 deletions sandwich/api/android/sandwich.api
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ public final class com/skydoves/sandwich/ResponseTransformer {
public static final synthetic fun recover (Lcom/skydoves/sandwich/ApiResponse;Ljava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun recover (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function0;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun recoverWith (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun requireNotNull (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun requireNotNull$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun requireNotNull (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun requireNotNull$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun suspendFilter (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final synthetic fun suspendFilterNot (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final synthetic fun suspendFold (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Expand Down Expand Up @@ -138,8 +138,8 @@ public final class com/skydoves/sandwich/ResponseTransformer {
public static final synthetic fun toFlow (Lcom/skydoves/sandwich/ApiResponse;)Lkotlinx/coroutines/flow/Flow;
public static final synthetic fun toFlow (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static final synthetic fun toSuspendFlow (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final synthetic fun validate (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun validate$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun validate (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun validate$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun zip (Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun zip (Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun zip3 (Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function3;)Lcom/skydoves/sandwich/ApiResponse;
Expand Down
8 changes: 4 additions & 4 deletions sandwich/api/jvm/sandwich.api
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ public final class com/skydoves/sandwich/ResponseTransformer {
public static final synthetic fun recover (Lcom/skydoves/sandwich/ApiResponse;Ljava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun recover (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function0;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun recoverWith (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun requireNotNull (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun requireNotNull$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun requireNotNull (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun requireNotNull$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun suspendFilter (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final synthetic fun suspendFilterNot (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final synthetic fun suspendFold (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
Expand Down Expand Up @@ -138,8 +138,8 @@ public final class com/skydoves/sandwich/ResponseTransformer {
public static final synthetic fun toFlow (Lcom/skydoves/sandwich/ApiResponse;)Lkotlinx/coroutines/flow/Flow;
public static final synthetic fun toFlow (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static final synthetic fun toSuspendFlow (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static final synthetic fun validate (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun validate$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun validate (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;)Lcom/skydoves/sandwich/ApiResponse;
public static synthetic fun validate$default (Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ILjava/lang/Object;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun zip (Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun zip (Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function2;)Lcom/skydoves/sandwich/ApiResponse;
public static final synthetic fun zip3 (Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;Lcom/skydoves/sandwich/ApiResponse;Lkotlin/jvm/functions/Function3;)Lcom/skydoves/sandwich/ApiResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import com.skydoves.sandwich.mappers.ApiResponseFailureMapper
import com.skydoves.sandwich.mappers.ApiResponseFailureSuspendMapper
import com.skydoves.sandwich.operators.ApiResponseOperator
import com.skydoves.sandwich.operators.ApiResponseSuspendOperator
import kotlin.coroutines.cancellation.CancellationException
import kotlinx.coroutines.launch
import kotlin.coroutines.cancellation.CancellationException

/**
* @author skydoves (Jaewoong Eum)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ import com.skydoves.sandwich.mappers.ApiResponseMapper
import com.skydoves.sandwich.mappers.ApiSuccessModelMapper
import com.skydoves.sandwich.operators.ApiResponseOperator
import com.skydoves.sandwich.operators.ApiResponseSuspendOperator
import kotlin.coroutines.cancellation.CancellationException
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flowOf
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.coroutines.cancellation.CancellationException
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmSynthetic
Expand Down Expand Up @@ -1087,21 +1087,18 @@ public suspend inline fun <T> ApiResponse<T>.suspendRecoverWith(
* If the predicate returns false, the response is converted to [ApiResponse.Failure.Error].
*
* @param predicate A predicate function that validates the success data.
* @param errorMessage A lambda that provides the error message when validation fails.
* @param errorMessage The error message when validation fails.
*
* @return The original [ApiResponse.Success] if validation passes, otherwise [ApiResponse.Failure.Error].
*/
@JvmSynthetic
public inline fun <T> ApiResponse<T>.validate(
crossinline predicate: (T) -> Boolean,
crossinline errorMessage: () -> String = { "Validation failed" },
errorMessage: String = "Validation failed",
): ApiResponse<T> {
contract {
callsInPlace(predicate, InvocationKind.AT_MOST_ONCE)
callsInPlace(errorMessage, InvocationKind.AT_MOST_ONCE)
}
contract { callsInPlace(predicate, InvocationKind.AT_MOST_ONCE) }
if (this is ApiResponse.Success && !predicate(data)) {
return ApiResponse.Failure.Error(payload = errorMessage())
return ApiResponse.Failure.Error(payload = errorMessage)
}
return this
}
Expand Down Expand Up @@ -1137,26 +1134,23 @@ public suspend inline fun <T> ApiResponse<T>.suspendValidate(
* If the selected value is null, the response is converted to [ApiResponse.Failure.Error].
*
* @param selector A selector function that extracts a nullable value from the success data.
* @param errorMessage A lambda that provides the error message when the selected value is null.
* @param errorMessage The error message when the selected value is null.
*
* @return An [ApiResponse] with the non-null selected value, or [ApiResponse.Failure.Error] if null.
*/
@Suppress("UNCHECKED_CAST")
@JvmSynthetic
public inline fun <T, R> ApiResponse<T>.requireNotNull(
crossinline selector: (T) -> R?,
crossinline errorMessage: () -> String = { "Required value was null" },
errorMessage: String = "Required value was null",
): ApiResponse<R> {
contract {
callsInPlace(selector, InvocationKind.AT_MOST_ONCE)
callsInPlace(errorMessage, InvocationKind.AT_MOST_ONCE)
}
contract { callsInPlace(selector, InvocationKind.AT_MOST_ONCE) }
if (this is ApiResponse.Success) {
val selected = selector(data)
return if (selected != null) {
ApiResponse.Success(data = selected, tag = tag)
} else {
ApiResponse.Failure.Error(payload = errorMessage())
ApiResponse.Failure.Error(payload = errorMessage)
}
}
return this as ApiResponse<R>
Expand Down