Davide Giuseppe Farella
02/20/2023, 4:20 PMEither<Left, Right>
, where Left
is sealed interface Left { A; B }
I want Right
if one of the two Either is Right; otherwise, the Either which Left
is A
, if any.
In other words, the priority is Right -> Left.A -> whatever
( don’t really need Left.B
)
Which would be the best way to achieve that?sealed interface GetAccountError {
data class NetworkError(...) : GetAccountError
object NotConnected : GetAccountError
}
val tmdbEither: Either<GetAccountError, Account>
val traktEither: Either<GetAccountError, Account>
I want Account
if any, otherwise, AccountError
if any, otherwise I know no account is connectedtmdbAccountUiModelEither.fold(
ifLeft = { accountError ->
if (accountError is GetAccountError.Network) {
return@combine ManageAccountState.Account.Error(
message = networkErrorMapper.toMessage(accountError.networkError)
)
}
},
ifRight = { account ->
return@combine ManageAccountState.Account.Connected(account)
}
)
traktAccountUiModelEither.fold(
ifLeft = { accountError ->
if (accountError is GetAccountError.Network) {
return@combine ManageAccountState.Account.Error(
message = networkErrorMapper.toMessage(accountError.networkError)
)
}
},
ifRight = { account ->
return@combine ManageAccountState.Account.Connected(account)
}
)
return@combine ManageAccountState.Account.NotConnected
simon.vergauwen
02/20/2023, 5:52 PMreturn@combine
is doing here 🤔
If I understand correctly, with 1.2.6-alpha.28
you can write:
fun GetAccountError.Network.toManageError() =
ManageAccountState.Account.Error(
message = networkErrorMapper.toMessage(accountError.networkError)
tmdbEither.recover { e ->
if(e is NetworkError) raise(e.toManageError())
else traktEither.recover {
if(e is NetworkError) raise(e.toManageError())
else raise(ManageAccountState.Account.NotConnected)
}
}
}.map { ManageAccountState.Account.Connected(account) }
Or before:
fun GetAccountError.Network.toManageError() =
ManageAccountState.Account.Error(
message = networkErrorMapper.toMessage(accountError.networkError)
tmdbEither.handleErrorWith { e ->
if(e is NetworkError) e.toManageError().left()
else traktEither.handleErrorWith {
if(e is NetworkError) e.toManageError().left()
else ManageAccountState.Account.NotConnected.left()
}
}
}.map { ManageAccountState.Account.Connected(account) }
Davide Giuseppe Farella
02/20/2023, 5:56 PMreturn@combine
just because I'm inside the lambda of a combine
combine(
getTmbdAccount(),
getTraktAcoount()
) {
// Code above
}
simon.vergauwen
02/20/2023, 6:17 PMDavide Giuseppe Farella
02/21/2023, 7:29 AMoperator fun invoke(): Flow<Either<GetAccountError, Account>> = combine(
getTmdbAccount(),
getTraktAccount()
) { tmdbAccountEither, traktAccountEither ->
check(tmdbAccountEither.isLeft() || traktAccountEither.isLeft()) {
"Both accounts are connected: this is not supported"
}
tmdbAccountEither.handleErrorWith { tmdbError ->
traktAccountEither.handleErrorWith { traktError ->
if (tmdbError is GetAccountError.Network) {
tmdbError.left()
} else {
traktError.left()
}
}
}
}