Skip to content

Commit

Permalink
Merge pull request #21 from soil-kt/refactor-loadable
Browse files Browse the repository at this point in the history
Loadable implements QueryModel
  • Loading branch information
ogaclejapan committed May 12, 2024
2 parents 772b159 + c2af7d1 commit b3d9ad5
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,6 @@ import soil.query.compose.QueryRefreshErrorObject
import soil.query.compose.QuerySuccessObject
import soil.query.internal.uuid

@Composable
inline fun <T> Await(
state: Loadable<T>,
key: Any? = null,
host: AwaitHost = LocalAwaitHost.current,
content: @Composable (T) -> Unit
) {
val id = remember(key) { key ?: uuid() }
when (state) {
is Loadable.Fulfilled -> content(state.data)
is Loadable.Rejected,
is Loadable.Pending -> Unit
}
LaunchedEffect(id, state) {
host[id] = state is Loadable.Pending
}
DisposableEffect(id) {
onDispose {
host.remove(id)
}
}
}

/**
* Await for a [QueryModel] to be fulfilled.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,6 @@ import androidx.compose.runtime.remember
import soil.query.QueryModel
import soil.query.internal.uuid

@Composable
fun Catch(
state: Loadable<*>,
isEnabled: Boolean = true,
content: @Composable CatchScope.(err: Throwable) -> Unit = { Throw(error = it) }
) {
Catch(
state = state,
filterIsInstance = { it },
isEnabled = isEnabled,
content = content
)
}

@Composable
fun <T : Throwable> Catch(
state: Loadable<*>,
filterIsInstance: (err: Throwable) -> T?,
isEnabled: Boolean = true,
content: @Composable CatchScope.(err: T) -> Unit = { Throw(error = it) }
) {
when (state) {
is Loadable.Rejected -> {
val err = remember(state.error, isEnabled) {
state.error.takeIf { isEnabled }?.let(filterIsInstance)
}
if (err != null) {
with(CatchScope) { content(err) }
}
}

is Loadable.Fulfilled,
is Loadable.Pending -> Unit
}
}

/**
* Catch for a [QueryModel] to be rejected.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ package soil.query.compose.runtime

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import soil.query.QueryFetchStatus
import soil.query.QueryModel
import soil.query.QueryStatus
import soil.query.internal.epoch

// TODO QueryModel implementation
/**
* Promise-like data structure that represents the state of a value that is being loaded.
*
Expand All @@ -16,27 +19,55 @@ import androidx.compose.runtime.Stable
* @param T The type of the value that has been loaded.
*/
@Stable
sealed interface Loadable<out T> {
sealed class Loadable<out T> : QueryModel<T> {

/**
* Represents the state of a value that is being loaded.
*/
@Immutable
data object Pending : Loadable<Nothing>
data object Pending : Loadable<Nothing>() {
override val data: Nothing = throw IllegalStateException("Pending")
override val dataUpdatedAt: Long = 0
override val dataStaleAt: Long = 0
override val error: Throwable? = null
override val errorUpdatedAt: Long = 0
override val status: QueryStatus = QueryStatus.Pending
override val fetchStatus: QueryFetchStatus = QueryFetchStatus.Fetching
override val isInvalidated: Boolean = false
override val isPlaceholderData: Boolean = false
}

/**
* Represents the state of a value that has been loaded.
*/
@Immutable
data class Fulfilled<T>(
val data: T
) : Loadable<T>
override val data: T
) : Loadable<T>() {
override val dataUpdatedAt: Long = epoch()
override val dataStaleAt: Long = Long.MAX_VALUE
override val error: Throwable? = null
override val errorUpdatedAt: Long = 0
override val status: QueryStatus = QueryStatus.Success
override val fetchStatus: QueryFetchStatus = QueryFetchStatus.Idle
override val isInvalidated: Boolean = false
override val isPlaceholderData: Boolean = false
}

/**
* Represents the state of a value that has been rejected.
*/
@Immutable
data class Rejected(
val error: Throwable
) : Loadable<Nothing>
override val error: Throwable
) : Loadable<Nothing>() {
override val data: Nothing = throw IllegalStateException("Rejected")
override val dataUpdatedAt: Long = 0
override val dataStaleAt: Long = 0
override val errorUpdatedAt: Long = epoch()
override val status: QueryStatus = QueryStatus.Failure
override val fetchStatus: QueryFetchStatus = QueryFetchStatus.Idle
override val isInvalidated: Boolean = false
override val isPlaceholderData: Boolean = false
}
}

0 comments on commit b3d9ad5

Please sign in to comment.