Advertisement
Guest User

Untitled

a guest
Jul 21st, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.44 KB | None | 0 0
  1. import kotlinx.coroutines.CompletableDeferred
  2. import retrofit2.*
  3. import java.lang.reflect.ParameterizedType
  4. import java.lang.reflect.Type
  5.  
  6. class ResponseResultCallAdapter private constructor() : CallAdapter.Factory() {
  7.     companion object {
  8.         @JvmStatic
  9.         @JvmName("create")
  10.         operator fun invoke() = ResponseResultCallAdapter()
  11.     }
  12.  
  13.     override fun get(
  14.         returnType: Type,
  15.         annotations: Array<out Annotation>,
  16.         retrofit: Retrofit
  17.     ): CallAdapter<*, *>? {
  18.         if (ResponseResult::class.java != getRawType(returnType)) {
  19.             return null
  20.         }
  21.         if (returnType !is ParameterizedType) {
  22.             throw IllegalStateException(
  23.                 "Deferred return type must be parameterized as Deferred<Foo> or Deferred<out Foo>"
  24.             )
  25.         }
  26.         val responseType = getParameterUpperBound(0, returnType)
  27.  
  28.         val rawDeferredType = getRawType(responseType)
  29.         return if (rawDeferredType == Response::class.java) {
  30.             if (responseType !is ParameterizedType) {
  31.                 throw IllegalStateException(
  32.                     "Response must be parameterized as Response<Foo> or Response<out Foo>"
  33.                 )
  34.             }
  35.             ResponseCallAdapter<Any>(getParameterUpperBound(0, responseType))
  36.         } else {
  37.             BodyCallAdapter<Any>(responseType)
  38.         }
  39.     }
  40.  
  41.     private class BodyCallAdapter<T>(private val responseType: Type) :
  42.         CallAdapter<T, CompletableDeferred<ResponseResult<T>>> {
  43.  
  44.         override fun responseType() = responseType
  45.  
  46.         override fun adapt(call: Call<T>): CompletableDeferred<ResponseResult<T>> {
  47.             val deferred = CompletableDeferred<ResponseResult<T>>()
  48.  
  49.             deferred.invokeOnCompletion {
  50.                 if (deferred.isCancelled) {
  51.                     call.cancel()
  52.                 }
  53.             }
  54.  
  55.             call.enqueue(object : Callback<T> {
  56.                 override fun onFailure(call: Call<T>, t: Throwable) {
  57.                     deferred.completeExceptionally(t)
  58.                 }
  59.  
  60.                 override fun onResponse(call: Call<T>, response: Response<T>) {
  61.                     if (response.isSuccessful) {
  62.                         deferred.complete(ResponseResult.Success<T>(response.body()!!))
  63.                     } else {
  64.                         deferred.completeExceptionally(HttpException(response))
  65.                     }
  66.                 }
  67.             })
  68.  
  69.             return deferred
  70.         }
  71.     }
  72.  
  73.     private class ResponseCallAdapter<T>(private val responseType: Type) :
  74.         CallAdapter<T, CompletableDeferred<ResponseResult<T>>> {
  75.  
  76.         override fun responseType() = responseType
  77.  
  78.         override fun adapt(call: Call<T>): CompletableDeferred<ResponseResult<T>> {
  79.             val deferred = CompletableDeferred<ResponseResult<T>>()
  80.  
  81.             call.enqueue(object : Callback<T> {
  82.                 override fun onFailure(call: Call<T>, t: Throwable) {
  83.                     deferred.completeExceptionally(t)
  84.                 }
  85.  
  86.                 override fun onResponse(call: Call<T>, response: Response<T>) {
  87.                     deferred.complete(ResponseResult.Success<T>(response.body()!!))
  88.                 }
  89.             })
  90.  
  91.             return deferred
  92.         }
  93.     }
  94. }
  95.  
  96. sealed class ResponseResult<T> {
  97.     class Success<T>(val value: T) : ResponseResult<T>()
  98.     class Error<T>(val statusCode: Int) : ResponseResult<T>()
  99. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement