forked from arrow-kt/arrow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ArrowEitherCallAdapter.kt
76 lines (60 loc) · 2.15 KB
/
ArrowEitherCallAdapter.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package arrow.retrofit.adapter.either
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import okhttp3.Request
import okhttp3.ResponseBody
import okio.Timeout
import retrofit2.Call
import retrofit2.CallAdapter
import retrofit2.Callback
import retrofit2.Converter
import retrofit2.Response
import retrofit2.Retrofit
import java.lang.reflect.Type
internal class ArrowEitherCallAdapter<E, R>(
retrofit: Retrofit,
errorType: Type,
private val bodyType: Type
) : CallAdapter<R, Call<Either<E, R>>> {
private val errorConverter: Converter<ResponseBody, E> =
retrofit.responseBodyConverter(errorType, arrayOfNulls(0))
override fun adapt(call: Call<R>): Call<Either<E, R>> = EitherCall(call, errorConverter, bodyType)
override fun responseType(): Type = bodyType
class EitherCall<E, R>(
private val original: Call<R>,
private val errorConverter: Converter<ResponseBody, E>,
private val bodyType: Type
) : Call<Either<E, R>> {
override fun enqueue(callback: Callback<Either<E, R>>) {
original.enqueue(object : Callback<R> {
override fun onFailure(call: Call<R>, t: Throwable) {
callback.onFailure(this@EitherCall, t)
}
override fun onResponse(call: Call<R>, response: Response<R>) {
onResponseFn(
callback,
this@EitherCall,
errorConverter,
bodyType,
response,
{ body, _ ->
Response.success(response.code(), body.right())
},
{ errorBody, _ ->
Response.success(errorBody.left())
}
)
}
})
}
override fun isExecuted(): Boolean = original.isExecuted
override fun timeout(): Timeout = original.timeout()
override fun clone(): Call<Either<E, R>> = EitherCall(original.clone(), errorConverter, bodyType)
override fun isCanceled(): Boolean = original.isCanceled
override fun cancel() = original.cancel()
override fun execute(): Response<Either<E, R>> =
throw UnsupportedOperationException("This adapter does not support sync execution")
override fun request(): Request = original.request()
}
}