Skip to content

Instantly share code, notes, and snippets.

@Cotel
Created July 8, 2019 08:08
Show Gist options
  • Save Cotel/552a70d066e040b44bdf3e766684ce7e to your computer and use it in GitHub Desktop.
Save Cotel/552a70d066e040b44bdf3e766684ce7e to your computer and use it in GitHub Desktop.
import arrow.core.Either
import arrow.core.left
import arrow.core.right
class JsonUser
class User
fun JsonUser.toUser(): User = throw RuntimeException()
sealed class UserQueryErrors {
object UserNotFound : UserQueryErrors()
object NetworkError : UserQueryErrors()
object MappingError : UserQueryErrors()
object DatabaseAuthError : UserQueryErrors()
}
interface NetworkDatasource {
fun isNetworkAvailable(): Boolean
fun findUserById(id: String): JsonUser?
}
interface DatabaseDatasource {
fun findUserById(id: String): User?
}
class DomainMapper {
fun jsonUserToUser(jsonUser: JsonUser): Either<UserQueryErrors, User> =
try {
jsonUser.toUser().right()
} catch (ex: Exception) {
UserQueryErrors.MappingError.left()
}
}
class UserRepository(
private val mapper: DomainMapper,
private val network: NetworkDatasource,
private val database: DatabaseDatasource
) {
private var networkPriority = true
fun findUser(id: String): Either<UserQueryErrors, User> =
if (networkPriority) {
if (network.isNetworkAvailable()) {
val jsonUser = network.findUserById(id)
if (jsonUser == null) UserQueryErrors.UserNotFound.left()
else mapper.jsonUserToUser(jsonUser)
} else UserQueryErrors.NetworkError.left()
} else {
try {
val user = database.findUserById(id)
user?.right() ?: UserQueryErrors.UserNotFound.left()
} catch (ex: Exception) {
UserQueryErrors.DatabaseAuthError.left()
}
}
}
class UserPresenter(private val repository: UserRepository) {
fun fetchUser() {
val either = repository.findUser("abc")
either.fold(
ifLeft = ::handleUserQueryError,
ifRight = ::handleUser
)
}
private fun handleUserQueryError(error: UserQueryErrors) = when (error) {
UserQueryErrors.UserNotFound -> println("User with id abc was not found")
UserQueryErrors.NetworkError -> println("There was an error with network")
UserQueryErrors.MappingError -> println("There was an error while processing")
UserQueryErrors.DatabaseAuthError -> println("There was an error with database")
}
private fun handleUser(user: User) {
println(user)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment