All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.http4k.connect.Paged.kt Maven / Gradle / Ivy

There is a newer version: 5.41.0.0
Show newest version
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