Created
September 16, 2019 22:36
-
-
Save ncipollo/4d404ce4197f0d236a77ace3ec14f944 to your computer and use it in GitHub Desktop.
Retrofit call adapter factory for Flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.mtg.api | |
import kotlinx.coroutines.flow.Flow | |
import kotlinx.coroutines.flow.flow | |
import retrofit2.* | |
import java.lang.reflect.ParameterizedType | |
import java.lang.reflect.Type | |
class FlowCallAdapterFactory private constructor() : CallAdapter.Factory() { | |
companion object { | |
fun create() = FlowCallAdapterFactory() | |
} | |
override fun get( | |
returnType: Type, | |
annotations: Array<Annotation>, | |
retrofit: Retrofit | |
): CallAdapter<*, *>? { | |
if (Flow::class.java != getRawType(returnType)) { | |
return null | |
} | |
check(returnType is ParameterizedType) { | |
"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) { | |
check(responseType is ParameterizedType) { | |
"Response must be parameterized as Response<Foo> or Response<out Foo>" | |
} | |
ResponseCallAdapter<Any>(getParameterUpperBound(0, responseType)) | |
} else { | |
BodyCallAdapter<Any>(responseType) | |
} | |
} | |
private class BodyCallAdapter<T : Any>( | |
private val responseType: Type | |
) : CallAdapter<T, Flow<T>> { | |
override fun responseType() = responseType | |
override fun adapt(call: Call<T>): Flow<T> = flow { emit(call.await()) } | |
} | |
private class ResponseCallAdapter<T : Any>( | |
private val responseType: Type | |
) : CallAdapter<T, Flow<Response<T>>> { | |
override fun responseType() = responseType | |
override fun adapt(call: Call<T>): Flow<Response<T>> = flow { emit(call.awaitResponse()) } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment