Replace Either with Kotlin Result and optimize ListUtils (#4443)

Using `Either<Throwable, T>` is basically the same as `Result<T>` with a
less friendly API. Futhermore, `Either` is currently only used in a
single component.

- Replace `Either` with `Result` in `AccountsInListFragment` and
`AccountsInListViewModel`.
- Add a method to convert a `NetworkResult` to a `Result` in
`AccountsInListViewModel`. Alternatively, `NetworkResult` could be used
everywhere in the code but other classes are already using `Result`.
- Replace `updateState()` method with `MutableStateFlow.update()` in
`AccountsInListViewModel`.
- Store the current search query in a `MutableStateFlow` collected by a
coroutine. This allows automatically cancelling the previous search when
a new query arrives, instead of launching a new coroutine for each query
which may conflict with the previous ones.
- Optimize `ListUtils`.
This commit is contained in:
Christophe Beyls 2024-05-31 12:58:24 +02:00 committed by GitHub
commit 2cbd629150
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 72 additions and 114 deletions

View file

@ -1,49 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.util
/**
* Created by charlag on 05/11/17.
*
* Class to represent sum type/tagged union/variant/ADT e.t.c.
* It is either Left or Right.
*/
sealed interface Either<out L, out R> {
data class Left<out L, out R>(val value: L) : Either<L, R>
data class Right<out L, out R>(val value: R) : Either<L, R>
fun isRight(): Boolean = this is Right
fun isLeft(): Boolean = this is Left
fun asLeftOrNull(): L? = (this as? Left<L, R>)?.value
fun asRightOrNull(): R? = (this as? Right<L, R>)?.value
fun asLeft(): L = (this as Left<L, R>).value
fun asRight(): R = (this as Right<L, R>).value
companion object {
inline fun <L, R, N> Either<L, R>.map(mapper: (R) -> N): Either<L, N> {
return if (this.isLeft()) {
Left(this.asLeft())
} else {
Right(mapper(this.asRight()))
}
}
}
}

View file

@ -17,31 +17,36 @@
package com.keylesspalace.tusky.util
import java.util.ArrayList
import java.util.LinkedHashSet
/**
* Copies elements to destination, removing duplicates and preserving original order.
*/
fun <T, C : MutableCollection<in T>> Iterable<T>.removeDuplicatesTo(destination: C): C {
return filterTo(destination, HashSet<T>()::add)
}
/**
* @return a new ArrayList containing the elements without duplicates in the same order
* Copies elements to a new list, removing duplicates and preserving original order.
*/
fun <T> removeDuplicates(list: List<T>): ArrayList<T> {
val set = LinkedHashSet(list)
return ArrayList(set)
fun <T> Iterable<T>.removeDuplicates(): List<T> {
return removeDuplicatesTo(ArrayList())
}
inline fun <T> List<T>.withoutFirstWhich(predicate: (T) -> Boolean): List<T> {
val newList = toMutableList()
val index = newList.indexOfFirst(predicate)
if (index != -1) {
newList.removeAt(index)
val index = indexOfFirst(predicate)
if (index == -1) {
return this
}
val newList = toMutableList()
newList.removeAt(index)
return newList
}
inline fun <T> List<T>.replacedFirstWhich(replacement: T, predicate: (T) -> Boolean): List<T> {
val newList = toMutableList()
val index = newList.indexOfFirst(predicate)
if (index != -1) {
newList[index] = replacement
val index = indexOfFirst(predicate)
if (index == -1) {
return this
}
val newList = toMutableList()
newList[index] = replacement
return newList
}