From 92c4784e42c4cf39a746677b9592a85dc20a76db Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 26 May 2024 22:59:19 +0600 Subject: [PATCH] paginations improvements --- CHANGELOG.md | 7 ++++ gradle/libs.versions.toml | 4 +-- .../pagination/PaginationResult.kt | 17 +++++++++- .../micro_utils/pagination/WalkPagination.kt | 27 +++++++++++---- .../micro_utils/pagination/utils/DoForAll.kt | 4 +-- .../micro_utils/pagination/utils/GetAll.kt | 4 +-- .../micro_utils/pagination/utils/Paginate.kt | 9 ++--- .../pagination/utils/PaginationPaging.kt | 34 +++++++++++++++++++ 8 files changed, 89 insertions(+), 17 deletions(-) create mode 100644 pagination/common/src/commonTest/kotlin/dev/inmo/micro_utils/pagination/utils/PaginationPaging.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index cce35511040..e344a00e8d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## 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 * `Versions`: diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c28a0158cd1..84313b0b175 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -26,13 +26,13 @@ kotlin-poet = "1.16.0" versions = "0.51.0" -android-gradle = "8.3.2" +android-gradle = "8.2.0" dexcount = "4.0.0" android-coreKtx = "1.13.1" android-recyclerView = "1.3.2" android-appCompat = "1.6.1" -android-fragment = "1.7.0" +android-fragment = "1.7.1" android-espresso = "3.5.1" android-test = "1.1.5" android-compose-material3 = "1.2.1" diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt index 9c88e91c53a..28accc46693 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/PaginationResult.kt @@ -20,7 +20,13 @@ data class PaginationResult( * Amount of pages for current pagination */ @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( page: Int, @@ -35,6 +41,15 @@ data class PaginationResult( ) } +val PaginationResult<*>.lastPageLong + get() = pagesNumberLong - 1 + +val PaginationResult<*>.lastPage + get() = lastPageLong.toInt() + +val PaginationResult<*>.isLastPage + get() = page.toLong() == lastPageLong + fun emptyPaginationResult() = PaginationResult(0, 0, emptyList(), 0L) fun emptyPaginationResult( basePagination: Pagination diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/WalkPagination.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/WalkPagination.kt index e46baf20d68..2c39ff4588a 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/WalkPagination.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/WalkPagination.kt @@ -10,8 +10,7 @@ inline fun doWithPagination( } } -@Suppress("NOTHING_TO_INLINE") -inline fun PaginationResult<*>.nextPageIfNotEmpty() = if (results.isNotEmpty()) { +inline fun > PR.nextPageIfTrue(condition: PR.() -> Boolean) = if (condition()) { SimplePagination( page + 1, size @@ -20,12 +19,28 @@ inline fun PaginationResult<*>.nextPageIfNotEmpty() = if (results.isNotEmpty()) null } -@Suppress("NOTHING_TO_INLINE") -inline fun PaginationResult.thisPageIfNotEmpty(): PaginationResult? = if (results.isNotEmpty()) { +inline fun > PR.thisPageIfTrue(condition: PR.() -> Boolean): PR? = if (condition()) { this } else { null } -@Suppress("NOTHING_TO_INLINE") -inline fun PaginationResult.currentPageIfNotEmpty() = thisPageIfNotEmpty() +fun PaginationResult<*>.nextPageIfNotEmpty() = nextPageIfTrue { results.isNotEmpty() } + +fun PaginationResult.thisPageIfNotEmpty(): PaginationResult? = thisPageIfTrue { results.isNotEmpty() } + +fun PaginationResult.currentPageIfNotEmpty() = thisPageIfNotEmpty() + + +fun PaginationResult<*>.nextPageIfNotEmptyOrLastPage() = nextPageIfTrue { results.isNotEmpty() && !this.isLastPage } + +fun PaginationResult.thisPageIfNotEmptyOrLastPage(): PaginationResult? = thisPageIfTrue { results.isNotEmpty() && !this.isLastPage } + +fun PaginationResult.currentPageIfNotEmptyOrLastPage() = thisPageIfNotEmptyOrLastPage() + + +fun PaginationResult<*>.nextPageIfNotLastPage() = nextPageIfTrue { !this.isLastPage } + +fun PaginationResult.thisPageIfNotLastPage(): PaginationResult? = thisPageIfTrue { !this.isLastPage } + +fun PaginationResult.currentPageIfNotLastPage() = thisPageIfNotLastPage() diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/DoForAll.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/DoForAll.kt index 63e8cb38eba..7bdb926e406 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/DoForAll.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/DoForAll.kt @@ -18,7 +18,7 @@ inline fun doForAllWithNextPaging( ) { doForAll( initialPagination, - { it.nextPageIfNotEmpty() }, + { it.nextPageIfNotEmptyOrLastPage() }, block ) } @@ -29,7 +29,7 @@ inline fun doAllWithCurrentPaging( ) { doForAll( initialPagination, - { it.currentPageIfNotEmpty() }, + { it.nextPageIfNotEmptyOrLastPage() }, block ) } diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/GetAll.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/GetAll.kt index da50a9528e2..50ef92769c7 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/GetAll.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/GetAll.kt @@ -31,7 +31,7 @@ inline fun getAllWithNextPaging( block: (Pagination) -> PaginationResult ): List = getAll( initialPagination, - { it.nextPageIfNotEmpty() }, + { it.nextPageIfNotEmptyOrLastPage() }, block ) @@ -48,7 +48,7 @@ inline fun getAllWithCurrentPaging( block: (Pagination) -> PaginationResult ): List = getAll( initialPagination, - { it.currentPageIfNotEmpty() }, + { it.thisPageIfNotEmptyOrLastPage() }, block ) diff --git a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt index 6414e4aa01d..dddfd4eb874 100644 --- a/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt +++ b/pagination/common/src/commonMain/kotlin/dev/inmo/micro_utils/pagination/utils/Paginate.kt @@ -21,8 +21,9 @@ fun Iterable.paginate(with: Pagination): PaginationResult { } fun List.paginate(with: Pagination): PaginationResult { - val firstIndex = maxOf(with.firstIndex, 0) - val lastIndex = minOf(with.lastIndexExclusive, size) + val indices = indices + val firstIndex = with.firstIndex.coerceIn(indices) + val lastIndex = with.lastIndex.coerceIn(indices) + 1 // up to size if (firstIndex > lastIndex) { return emptyPaginationResult() } @@ -38,8 +39,8 @@ fun List.paginate(with: Pagination, reversed: Boolean): PaginationResult< reversed ) - val firstIndex = maxOf(actualPagination.firstIndex, 0) - val lastIndex = minOf(actualPagination.lastIndexExclusive, size) + val firstIndex = actualPagination.firstIndex.coerceIn(indices) + val lastIndex = actualPagination.lastIndex.coerceIn(indices) + 1 // up to size if (firstIndex > lastIndex) { return emptyPaginationResult() } diff --git a/pagination/common/src/commonTest/kotlin/dev/inmo/micro_utils/pagination/utils/PaginationPaging.kt b/pagination/common/src/commonTest/kotlin/dev/inmo/micro_utils/pagination/utils/PaginationPaging.kt new file mode 100644 index 00000000000..aef18c6948e --- /dev/null +++ b/pagination/common/src/commonTest/kotlin/dev/inmo/micro_utils/pagination/utils/PaginationPaging.kt @@ -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) + } +}