Created
August 19, 2020 14:50
-
-
Save rharter/9e95448a85e2f95b2179e642a748423c to your computer and use it in GitHub Desktop.
Extension function to convert a store, which emits a stream of **events**, to a repository which emits a stream of **states**. This hides implementation details, like which datasource is providing the data, from consumers.
This file contains 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
sealed class Resource<T> { | |
data class Loading<T>(val data: T? = null, val message: Int? = null) : Resource<T>() | |
data class Success<T>(val data: T) : Resource<T>() | |
data class Error<T>(val throwable: Throwable?, val data: T? = null) : Resource<T>() | |
} | |
fun <T> Resource<T>.dataOrNull(): T? = when (this) { | |
is Resource.Loading -> data | |
is Resource.Success -> data | |
is Resource.Error -> data | |
} | |
fun <T : Any> Flow<StoreResponse<T>>.asRepository(): Flow<Resource<T>> = flow { | |
var loading = false | |
var errorResponse: StoreResponse.Error<T>? = null | |
var data: T? = null | |
fun <T> StoreResponse.Error<T>.throwable(): Throwable = when (this) { | |
is StoreResponse.Error.Exception -> error | |
is StoreResponse.Error.Message -> Throwable(message) | |
} | |
suspend fun emitState() { | |
val error = errorResponse | |
when { | |
loading -> emit(Resource.Loading(data)) | |
error != null -> emit(Resource.Error(error.throwable(), data)) | |
else -> emit(Resource.Success(checkNotNull(data))) | |
} | |
} | |
collect { | |
if (it is StoreResponse.Loading) { | |
loading = true | |
} else if (it.origin == ResponseOrigin.Fetcher) { | |
loading = false | |
} | |
if (it is StoreResponse.Error) { | |
errorResponse = it | |
} else if (errorResponse?.origin == it.origin) { | |
errorResponse = null | |
} | |
if (it is StoreResponse.Data) { | |
data = it.value | |
} | |
emitState() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment