У меня в настоящее время есть конечные точки login
и register
, которые возвращают аналогичные JSON, первая возвращает токен JWT, а вторая - идентификатор пользователя, в любом случае в моем хранилище у меня есть код:
suspend fun login(user: User) = try {
val response = api.login(user)
LoginResult.Content(response.token)
} catch (t: Throwable) {
LoginResult.Error(t)
}
suspend fun register(user: User) = try {
val response = api.register(user)
RegisterResult.Content(response.id!!)
} catch (t: Throwable) {
RegisterResult.Error(t)
}
Мой LoginResult
выглядит следующим образом:
sealed class LoginResult {
data class Content(val accessToken: String) : LoginResult()
data class Error(val throwable: Throwable) : LoginResult()
}
и мой RegisterResult
выглядит очень похоже:
sealed class RegisterResult {
data class Content(val id: Int) : RegisterResult()
data class Error(val throwable: Throwable) : RegisterResult()
}
Очевидно, у меня много дублирующегося кода между этими двумя и учитывая, что у меня будет еще много запросов на обработку, будет только хуже. Помимо этого, есть также соответствующие ViewStates, о которых стоит подумать.
sealed class LoginViewState {
object Loading : LoginViewState()
data class Content(val accessToken: String) : LoginViewState()
data class Error(val throwable: Throwable) : LoginViewState()
}
Аналогичный существует для регистра, и они используются в Motors:
class LoginMotor : ViewModel() {
private val _results = MutableLiveData<LoginViewState>()
val results: LiveData<LoginViewState> = _results
fun login(user: User) {
_results.value = LoginViewState.Loading
viewModelScope.launch(Dispatchers.Main) {
val result = AuthRepository.login(user)
_results.value = when (result) {
is LoginResult.Content -> { LoginViewState.Content(result.accessToken) }
is LoginResult.Error -> LoginViewState.Error(result.throwable)
}
}
}
}
и другом таком двигателе для Регистрация. Сейчас я пытаюсь использовать обобщенный c подход и могу добавить обобщенные значения к EndpointResult
, но как мне сделать ViewState
generi c, когда мне нужно использовать состояние Loading
, которое объект и не может быть обобщенным c, так как это синглтон? Это не работает:
sealed class DataViewState<T> {
object Loading : LoginViewState() //error
data class Content<T>(val data: T) : LoginViewState<T>()
data class Error(val throwable: Throwable) : LoginViewState()
}