Skip to content

Instantly share code, notes, and snippets.

@marenovakovic
Last active November 19, 2018 01:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marenovakovic/bc6e32d120234705d4b218a35bc2e7a1 to your computer and use it in GitHub Desktop.
Save marenovakovic/bc6e32d120234705d4b218a35bc2e7a1 to your computer and use it in GitHub Desktop.
package com.marko.domain.usecase
import com.marko.domain.CoroutineDispatchers
import com.marko.domain.result.Result
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.withContext
abstract class UseCase<in P, R>(private val coroutineDispatchers: CoroutineDispatchers) {
protected abstract suspend fun execute(parameters: P): R
suspend operator fun invoke(
parameters: P,
block: suspend (channel: ReceiveChannel<Result<R>>) -> Unit
) {
val channel = Channel<Result<R>>()
block(channel)
try {
withContext(coroutineDispatchers.io) {
channel.send(Result.Loading)
execute(parameters).let {
channel.send(Result.Success(it))
}
}
} catch (e: Exception) {
channel.send(Result.Error(e))
} finally {
channel.close()
}
}
suspend operator fun invoke(parameters: P): Result<R> = try {
withContext(coroutineDispatchers.io) {
execute(parameters).let {
Result.Success(it)
}
}
} catch (e: Exception) {
Result.Error(e)
}
suspend fun unsafe(parameters: P): R =
withContext(coroutineDispatchers.io) { execute(parameters) }
}
suspend operator fun <R> UseCase<Unit, R>.invoke(block: suspend (state: ReceiveChannel<Result<R>>) -> Unit) =
this.invoke(Unit, block)
suspend operator fun <R> UseCase<Unit, R>.invoke(): Result<R> = this.invoke(Unit)
suspend fun <R> UseCase<Unit, R>.unsafe(): R = this.unsafe(Unit)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment