paginations improvements

This commit is contained in:
InsanusMokrassar 2024-05-26 22:59:19 +06:00
parent a634229dc0
commit 92c4784e42
8 changed files with 89 additions and 17 deletions

View File

@ -2,6 +2,13 @@
## 0.20.51 ## 0.20.51
* `Pagination`:
* Add `Pagination.nextPageIfTrue` and `Pagination.thisPageIftrue` extensions to get the page according to condition
pass status
* Add `PaginationResult.nextPageIfNotEmptyOrLastPage` and `PaginationResult.thisPageIfNotEmptyOrLastPage`
* Change all `doForAll` and `getAll` extensions fo pagination to work basing on `nextPageIfNotEmptyOrLastPage` and
`thisPageIfNotEmptyOrLastPage`
## 0.20.50 ## 0.20.50
* `Versions`: * `Versions`:

View File

@ -26,13 +26,13 @@ kotlin-poet = "1.16.0"
versions = "0.51.0" versions = "0.51.0"
android-gradle = "8.3.2" android-gradle = "8.2.0"
dexcount = "4.0.0" dexcount = "4.0.0"
android-coreKtx = "1.13.1" android-coreKtx = "1.13.1"
android-recyclerView = "1.3.2" android-recyclerView = "1.3.2"
android-appCompat = "1.6.1" android-appCompat = "1.6.1"
android-fragment = "1.7.0" android-fragment = "1.7.1"
android-espresso = "3.5.1" android-espresso = "3.5.1"
android-test = "1.1.5" android-test = "1.1.5"
android-compose-material3 = "1.2.1" android-compose-material3 = "1.2.1"

View File

@ -20,7 +20,13 @@ data class PaginationResult<T>(
* Amount of pages for current pagination * Amount of pages for current pagination
*/ */
@EncodeDefault @EncodeDefault
val pagesNumber: Int = ceil(objectsNumber / size.toFloat()).toInt() @SerialName("pagesNumber")
val pagesNumberLong: Long = ceil(objectsNumber / size.toFloat()).toLong()
/**
* Amount of pages for current pagination
*/
@Transient
val pagesNumber: Int = pagesNumberLong.toInt()
constructor( constructor(
page: Int, page: Int,
@ -35,6 +41,15 @@ data class PaginationResult<T>(
) )
} }
val PaginationResult<*>.lastPageLong
get() = pagesNumberLong - 1
val PaginationResult<*>.lastPage
get() = lastPageLong.toInt()
val PaginationResult<*>.isLastPage
get() = page.toLong() == lastPageLong
fun <T> emptyPaginationResult() = PaginationResult<T>(0, 0, emptyList(), 0L) fun <T> emptyPaginationResult() = PaginationResult<T>(0, 0, emptyList(), 0L)
fun <T> emptyPaginationResult( fun <T> emptyPaginationResult(
basePagination: Pagination basePagination: Pagination

View File

@ -10,8 +10,7 @@ inline fun doWithPagination(
} }
} }
@Suppress("NOTHING_TO_INLINE") inline fun <T, PR: PaginationResult<T>> PR.nextPageIfTrue(condition: PR.() -> Boolean) = if (condition()) {
inline fun PaginationResult<*>.nextPageIfNotEmpty() = if (results.isNotEmpty()) {
SimplePagination( SimplePagination(
page + 1, page + 1,
size size
@ -20,12 +19,28 @@ inline fun PaginationResult<*>.nextPageIfNotEmpty() = if (results.isNotEmpty())
null null
} }
@Suppress("NOTHING_TO_INLINE") inline fun <T, PR: PaginationResult<T>> PR.thisPageIfTrue(condition: PR.() -> Boolean): PR? = if (condition()) {
inline fun <T> PaginationResult<T>.thisPageIfNotEmpty(): PaginationResult<T>? = if (results.isNotEmpty()) {
this this
} else { } else {
null null
} }
@Suppress("NOTHING_TO_INLINE") fun PaginationResult<*>.nextPageIfNotEmpty() = nextPageIfTrue { results.isNotEmpty() }
inline fun <T> PaginationResult<T>.currentPageIfNotEmpty() = thisPageIfNotEmpty()
fun <T> PaginationResult<T>.thisPageIfNotEmpty(): PaginationResult<T>? = thisPageIfTrue { results.isNotEmpty() }
fun <T> PaginationResult<T>.currentPageIfNotEmpty() = thisPageIfNotEmpty()
fun PaginationResult<*>.nextPageIfNotEmptyOrLastPage() = nextPageIfTrue { results.isNotEmpty() && !this.isLastPage }
fun <T> PaginationResult<T>.thisPageIfNotEmptyOrLastPage(): PaginationResult<T>? = thisPageIfTrue { results.isNotEmpty() && !this.isLastPage }
fun <T> PaginationResult<T>.currentPageIfNotEmptyOrLastPage() = thisPageIfNotEmptyOrLastPage()
fun PaginationResult<*>.nextPageIfNotLastPage() = nextPageIfTrue { !this.isLastPage }
fun <T> PaginationResult<T>.thisPageIfNotLastPage(): PaginationResult<T>? = thisPageIfTrue { !this.isLastPage }
fun <T> PaginationResult<T>.currentPageIfNotLastPage() = thisPageIfNotLastPage()

View File

@ -18,7 +18,7 @@ inline fun <T> doForAllWithNextPaging(
) { ) {
doForAll( doForAll(
initialPagination, initialPagination,
{ it.nextPageIfNotEmpty() }, { it.nextPageIfNotEmptyOrLastPage() },
block block
) )
} }
@ -29,7 +29,7 @@ inline fun <T> doAllWithCurrentPaging(
) { ) {
doForAll( doForAll(
initialPagination, initialPagination,
{ it.currentPageIfNotEmpty() }, { it.nextPageIfNotEmptyOrLastPage() },
block block
) )
} }

View File

@ -31,7 +31,7 @@ inline fun <T> getAllWithNextPaging(
block: (Pagination) -> PaginationResult<T> block: (Pagination) -> PaginationResult<T>
): List<T> = getAll( ): List<T> = getAll(
initialPagination, initialPagination,
{ it.nextPageIfNotEmpty() }, { it.nextPageIfNotEmptyOrLastPage() },
block block
) )
@ -48,7 +48,7 @@ inline fun <T> getAllWithCurrentPaging(
block: (Pagination) -> PaginationResult<T> block: (Pagination) -> PaginationResult<T>
): List<T> = getAll( ): List<T> = getAll(
initialPagination, initialPagination,
{ it.currentPageIfNotEmpty() }, { it.thisPageIfNotEmptyOrLastPage() },
block block
) )

View File

@ -21,8 +21,9 @@ fun <T> Iterable<T>.paginate(with: Pagination): PaginationResult<T> {
} }
fun <T> List<T>.paginate(with: Pagination): PaginationResult<T> { fun <T> List<T>.paginate(with: Pagination): PaginationResult<T> {
val firstIndex = maxOf(with.firstIndex, 0) val indices = indices
val lastIndex = minOf(with.lastIndexExclusive, size) val firstIndex = with.firstIndex.coerceIn(indices)
val lastIndex = with.lastIndex.coerceIn(indices) + 1 // up to size
if (firstIndex > lastIndex) { if (firstIndex > lastIndex) {
return emptyPaginationResult() return emptyPaginationResult()
} }
@ -38,8 +39,8 @@ fun <T> List<T>.paginate(with: Pagination, reversed: Boolean): PaginationResult<
reversed reversed
) )
val firstIndex = maxOf(actualPagination.firstIndex, 0) val firstIndex = actualPagination.firstIndex.coerceIn(indices)
val lastIndex = minOf(actualPagination.lastIndexExclusive, size) val lastIndex = actualPagination.lastIndex.coerceIn(indices) + 1 // up to size
if (firstIndex > lastIndex) { if (firstIndex > lastIndex) {
return emptyPaginationResult() return emptyPaginationResult()
} }

View File

@ -0,0 +1,34 @@
package dev.inmo.micro_utils.pagination.utils
import dev.inmo.micro_utils.pagination.FirstPagePagination
import dev.inmo.micro_utils.pagination.firstIndex
import dev.inmo.micro_utils.pagination.isLastPage
import dev.inmo.micro_utils.pagination.lastIndexExclusive
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class PaginationPaging {
@Test
fun testPaginateOnList() {
val list = (0 until 7).toList()
val startPagination = FirstPagePagination(2)
var lastPageHappened = false
doForAllWithNextPaging(startPagination) {
val result = list.paginate(it)
if (result.isLastPage) {
lastPageHappened = true
assertTrue(result.results.size == 1)
}
val testSublist = list.subList(it.firstIndex, minOf(it.lastIndexExclusive, list.size))
assertEquals(result.results, testSublist)
result
}
assertTrue(lastPageHappened)
}
}