Merge pull request #453 from InsanusMokrassar/0.20.51

0.20.51
This commit is contained in:
InsanusMokrassar 2024-05-26 23:53:46 +06:00 committed by GitHub
commit fa8a5bcd97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 165 additions and 42 deletions

View File

@ -1,5 +1,16 @@
# Changelog
## 0.20.51
* `Versions`:
* `Android Fragment`: `1.7.0` -> `1.7.1`
* `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`:

View File

@ -15,5 +15,5 @@ crypto_js_version=4.1.1
# Project data
group=dev.inmo
version=0.20.50
android_code_version=256
version=0.20.51
android_code_version=257

View File

@ -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"

View File

@ -20,7 +20,13 @@ data class PaginationResult<T>(
* 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,31 +41,58 @@ data class PaginationResult<T>(
)
}
fun <T> emptyPaginationResult() = PaginationResult<T>(0, 0, emptyList(), 0L)
val PaginationResult<*>.lastPageLong
get() = pagesNumberLong - 1
val PaginationResult<*>.lastPage
get() = lastPageLong.toInt()
val PaginationResult<*>.isLastPage
get() = page.toLong() == lastPageLong
fun <T> emptyPaginationResult(
basePagination: Pagination
basePagination: Pagination,
objectsNumber: Number
) = PaginationResult<T>(
basePagination.page,
basePagination.size,
emptyList(),
0L
objectsNumber.toLong()
)
fun <T> emptyPaginationResult(
basePagination: Pagination,
) = emptyPaginationResult<T>(basePagination, 0)
fun <T> emptyPaginationResult() = emptyPaginationResult<T>(FirstPagePagination(0))
/**
* @return New [PaginationResult] with [data] without checking of data sizes equality
*/
inline fun <I, O> PaginationResult<I>.changeResultsUnchecked(
block: PaginationResult<I>.() -> List<O>
): PaginationResult<O> = PaginationResult(page, size, block(), objectsNumber)
/**
* @return New [PaginationResult] with [data] without checking of data sizes equality
*/
fun <I, O> PaginationResult<I>.changeResultsUnchecked(
data: List<O>
): PaginationResult<O> = PaginationResult(page, size, data, objectsNumber)
): PaginationResult<O> = changeResultsUnchecked { data }
/**
* @return New [PaginationResult] with [data] <b>with</b> checking of data sizes equality
*/
inline fun <I, O> PaginationResult<I>.changeResults(
block: PaginationResult<I>.() -> List<O>
): PaginationResult<O> {
val data = block()
require(data.size == results.size)
return changeResultsUnchecked(data)
}
/**
* @return New [PaginationResult] with [data] <b>with</b> checking of data sizes equality
*/
fun <I, O> PaginationResult<I>.changeResults(
data: List<O>
): PaginationResult<O> {
require(data.size == results.size)
return changeResultsUnchecked(data)
}
): PaginationResult<O> = changeResults { data }
fun <T> List<T>.createPaginationResult(
pagination: Pagination,

View File

@ -10,8 +10,7 @@ inline fun doWithPagination(
}
}
@Suppress("NOTHING_TO_INLINE")
inline fun PaginationResult<*>.nextPageIfNotEmpty() = if (results.isNotEmpty()) {
inline fun <T, PR: PaginationResult<T>> 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 <T> PaginationResult<T>.thisPageIfNotEmpty(): PaginationResult<T>? = if (results.isNotEmpty()) {
inline fun <T, PR: PaginationResult<T>> PR.thisPageIfTrue(condition: PR.() -> Boolean): PR? = if (condition()) {
this
} else {
null
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> PaginationResult<T>.currentPageIfNotEmpty() = thisPageIfNotEmpty()
fun PaginationResult<*>.nextPageIfNotEmpty() = nextPageIfTrue { results.isNotEmpty() }
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(
initialPagination,
{ it.nextPageIfNotEmpty() },
{ it.nextPageIfNotEmptyOrLastPage() },
block
)
}
@ -29,7 +29,7 @@ inline fun <T> doAllWithCurrentPaging(
) {
doForAll(
initialPagination,
{ it.currentPageIfNotEmpty() },
{ it.nextPageIfNotEmptyOrLastPage() },
block
)
}

View File

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

View File

@ -21,33 +21,25 @@ fun <T> Iterable<T>.paginate(with: Pagination): PaginationResult<T> {
}
fun <T> List<T>.paginate(with: Pagination): PaginationResult<T> {
val firstIndex = maxOf(with.firstIndex, 0)
val lastIndex = minOf(with.lastIndexExclusive, size)
if (firstIndex > lastIndex) {
return emptyPaginationResult()
if (with.firstIndex >= size || with.lastIndex < 0) {
return emptyPaginationResult(with, size.toLong())
}
return subList(firstIndex, lastIndex).createPaginationResult(
return asSequence().drop(with.firstIndex).take(with.size).toList().createPaginationResult(
with,
size.toLong()
)
}
fun <T> List<T>.paginate(with: Pagination, reversed: Boolean): PaginationResult<T> {
val actualPagination = with.optionallyReverse(
size,
reversed
)
val firstIndex = maxOf(actualPagination.firstIndex, 0)
val lastIndex = minOf(actualPagination.lastIndexExclusive, size)
if (firstIndex > lastIndex) {
return emptyPaginationResult()
return if (reversed) {
val actualPagination = with.optionallyReverse(
size,
reversed
)
paginate(actualPagination).changeResultsUnchecked { results.reversed() }
} else {
paginate(with)
}
return subList(firstIndex, lastIndex).optionallyReverse(reversed).createPaginationResult(
with,
size.toLong()
)
}
fun <T> Set<T>.paginate(with: Pagination): PaginationResult<T> {

View File

@ -0,0 +1,72 @@
package dev.inmo.micro_utils.pagination.utils
import dev.inmo.micro_utils.pagination.*
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
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)
}
@Test
fun testEmptyPaginateOnList() {
val list = listOf<Int>()
val startPagination = FirstPagePagination(2)
var paginationHappend = false
doForAllWithNextPaging(startPagination) {
val resultPagination = list.paginate(it)
assertEquals(resultPagination, emptyPaginationResult(it, list.size))
assertFalse(paginationHappend)
paginationHappend = true
resultPagination
}
assertTrue(paginationHappend)
}
@Test
fun testRightOutPaginateOnList() {
val list = (0 until 7).toList()
val startPagination = SimplePagination(page = 4, size = 2)
var paginationHappend = false
doForAllWithNextPaging(startPagination) {
val resultPagination = list.paginate(it)
assertEquals(resultPagination, emptyPaginationResult(it, list.size))
assertFalse(paginationHappend)
paginationHappend = true
resultPagination
}
assertTrue(paginationHappend)
}
}