mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-11-22 16:23:50 +00:00
commit
fa8a5bcd97
11
CHANGELOG.md
11
CHANGELOG.md
@ -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`:
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
|
@ -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> {
|
||||
return if (reversed) {
|
||||
val actualPagination = with.optionallyReverse(
|
||||
size,
|
||||
reversed
|
||||
)
|
||||
|
||||
val firstIndex = maxOf(actualPagination.firstIndex, 0)
|
||||
val lastIndex = minOf(actualPagination.lastIndexExclusive, size)
|
||||
if (firstIndex > lastIndex) {
|
||||
return emptyPaginationResult()
|
||||
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> {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user