Не может использовать встроенную функцию дооснащения - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь создать встроенную функцию с ответом Retrofit, но когда я нажимаю . и пытаюсь вызвать функцию, она не отображается, я пытаюсь без вызова и она видима.

У меня есть это

@GET("url")
suspend fun getModel(): Response<ModelEntity>

И моя встроенная функция

inline fun <T, R> safeCall(
    block: () -> Response<T>,
    transform: (T) -> R,
    errorFactory: FailureFactory = FailureFactory()
): Either<ErrorEntity, R> =
    try {
        val result = block()
        when (result.isSuccessful) {
            true -> Either.Right(transform(result.body()!!))
            false -> Either.Left(errorFactory.handleCode(result.code()))
        }
    } catch (exception: IOException) {
        Either.Left(errorFactory.handleException(exception))
    }

Но я не могу вызвать что-то вроде

service.myList().safeCall(...)

Даже если он возвращает Response<T>

Моя идея состоит в том, чтобы назвать его так

override fun getMessages() =
   service.getMessages()
         .safeCall(transform = { it.map { msgs-> msgs.toDomain() }})
}

1 Ответ

0 голосов
/ 26 апреля 2020

Вам нужно сделать свою функцию:

  1. Расширение типа, для которого вы хотите, чтобы он вызывался.
  2. сделать последним параметром transform, чтобы использовать его вне фигурных скобок (рекомендуется в чистая архитектура, не требуется).

Вы можете реализовать свою функцию следующим образом:

inline fun <T, R> Response<T>.safeCall(
    errorFactory: FailureFactory = FailureFactory(),
    transform: (T) -> R
): Either<ErrorEntity, R> =
    when (this.isSuccessful) {
        true -> Either.Right(transform(body()!!))
        false -> Either.Left(errorFactory.handleCode(code()))
    }

Теперь, поскольку ваш safeCall является расширением Response, теперь вы можете вызывать в ответе:

// response is of type Response<T> where T is Any?
response.safeCall(myErrorFactory) { it.map { msgs-> msgs.toDomain() } }

Редактировать:

Если вы хотите перехватывать исключения, при выполнении вызовов вы можете использовать этот подход:

inline fun <T, R> safeCall(
    block: () -> Response<T>,
    errorFactory: FailureFactory = FailureFactory(),
    transform: (T) -> R
): Either<ErrorEntity, R> = ... // your original function body

Для вызова этой функции:

// myErrorFactory optional
safeCall(service::mylist, myErrorFactory) { it.map { msgs-> msgs.toDomain() } }
safeCall(service::getMessages, myErrorFactory) { it.map { msgs-> msgs.toDomain() } }
...