org.http4k.connect.Paged.kt Maven / Gradle / Ivy
package org.http4k.connect
import dev.forkhandles.result4k.Failure
import dev.forkhandles.result4k.Result
import dev.forkhandles.result4k.Success
import dev.forkhandles.result4k.map
import org.http4k.core.Response
import org.http4k.format.AutoMarshalling
import org.http4k.lens.LensExtractor
import kotlin.reflect.KClass
/**
* Represents a Paged response
*/
interface Paged : Iterable {
fun token(): Token?
val items: List
override fun iterator() = items.iterator()
}
/**
* Superclass for all Paged actions
*/
interface PagedAction, Self : PagedAction> :
Action> {
fun next(token: Token): Self
}
/**
* Paginate the response of the passed action
*/
fun , Rsp : Paged> paginated(
fn: (Action) -> Result, action: Action
): Sequence, RemoteFailure>> {
var nextRequest: Action? = action
return generateSequence {
nextRequest
?.let {
fn(it).map { rsp ->
nextRequest = rsp.token()?.let(it::next)
rsp.items
}
}
}
}
/**
* Superclass for paged actions where the response can be auto-marshalled
*/
abstract class AutomarshalledPagedAction<
Token,
ItemType : Any,
PageType : Paged,
Self : AutomarshalledPagedAction
>(
private val toResult: (List, Token?) -> PageType,
private val autoMarshalling: AutoMarshalling,
private val kClass: KClass
) : PagedAction,
LensExtractor {
override fun toResult(response: Response): Result = with(response) {
when {
status.successful -> Success(
toResult(
autoMarshalling
.asA(
"""{"items":${bodyString()}}""".trimIndent(),
kClass
).items,
this@AutomarshalledPagedAction(this)
)
)
else -> Failure(RemoteFailure(toRequest().method, toRequest().uri, status, bodyString()))
}
}
override fun equals(other: Any?) = when {
this === other -> true
javaClass != other?.javaClass -> false
else -> toRequest() == (other as Action<*>).toRequest()
}
override fun hashCode() = toRequest().hashCode()
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy