Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import kotlinx.coroutines.CompletableDeferred
- import retrofit2.*
- import java.lang.reflect.ParameterizedType
- import java.lang.reflect.Type
- class ResponseResultCallAdapter private constructor() : CallAdapter.Factory() {
- companion object {
- @JvmStatic
- @JvmName("create")
- operator fun invoke() = ResponseResultCallAdapter()
- }
- override fun get(
- returnType: Type,
- annotations: Array<out Annotation>,
- retrofit: Retrofit
- ): CallAdapter<*, *>? {
- if (ResponseResult::class.java != getRawType(returnType)) {
- return null
- }
- if (returnType !is ParameterizedType) {
- throw IllegalStateException(
- "Deferred return type must be parameterized as Deferred<Foo> or Deferred<out Foo>"
- )
- }
- val responseType = getParameterUpperBound(0, returnType)
- val rawDeferredType = getRawType(responseType)
- return if (rawDeferredType == Response::class.java) {
- if (responseType !is ParameterizedType) {
- throw IllegalStateException(
- "Response must be parameterized as Response<Foo> or Response<out Foo>"
- )
- }
- ResponseCallAdapter<Any>(getParameterUpperBound(0, responseType))
- } else {
- BodyCallAdapter<Any>(responseType)
- }
- }
- private class BodyCallAdapter<T>(private val responseType: Type) :
- CallAdapter<T, CompletableDeferred<ResponseResult<T>>> {
- override fun responseType() = responseType
- override fun adapt(call: Call<T>): CompletableDeferred<ResponseResult<T>> {
- val deferred = CompletableDeferred<ResponseResult<T>>()
- deferred.invokeOnCompletion {
- if (deferred.isCancelled) {
- call.cancel()
- }
- }
- call.enqueue(object : Callback<T> {
- override fun onFailure(call: Call<T>, t: Throwable) {
- deferred.completeExceptionally(t)
- }
- override fun onResponse(call: Call<T>, response: Response<T>) {
- if (response.isSuccessful) {
- deferred.complete(ResponseResult.Success<T>(response.body()!!))
- } else {
- deferred.completeExceptionally(HttpException(response))
- }
- }
- })
- return deferred
- }
- }
- private class ResponseCallAdapter<T>(private val responseType: Type) :
- CallAdapter<T, CompletableDeferred<ResponseResult<T>>> {
- override fun responseType() = responseType
- override fun adapt(call: Call<T>): CompletableDeferred<ResponseResult<T>> {
- val deferred = CompletableDeferred<ResponseResult<T>>()
- call.enqueue(object : Callback<T> {
- override fun onFailure(call: Call<T>, t: Throwable) {
- deferred.completeExceptionally(t)
- }
- override fun onResponse(call: Call<T>, response: Response<T>) {
- deferred.complete(ResponseResult.Success<T>(response.body()!!))
- }
- })
- return deferred
- }
- }
- }
- sealed class ResponseResult<T> {
- class Success<T>(val value: T) : ResponseResult<T>()
- class Error<T>(val statusCode: Int) : ResponseResult<T>()
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement