org.http4k.contract.routeSpec.kt Maven / Gradle / Ivy
package org.http4k.contract
import org.http4k.core.Filter
import org.http4k.core.HttpHandler
import org.http4k.core.Request
import org.http4k.lens.BodyLens
import org.http4k.lens.Failure
import org.http4k.lens.Lens
import org.http4k.lens.LensFailure
import org.http4k.lens.Path
import org.http4k.lens.PathLens
abstract class ContractRouteSpec internal constructor(val pathFn: (PathSegments) -> PathSegments,
val requestParams: List>,
val body: BodyLens<*>?,
vararg val pathLenses: PathLens<*>) : Filter {
abstract infix operator fun div(next: PathLens): ContractRouteSpec
open infix operator fun div(next: String) = div(Path.fixed(next))
override fun invoke(nextHandler: HttpHandler): HttpHandler =
{ req ->
val body = body?.let { listOf(it::invoke) } ?: emptyList<(Request) -> Any?>()
val errors = body.plus(requestParams).fold(emptyList()) { memo, next ->
try {
next(req)
memo
} catch (e: LensFailure) {
memo.plus(e.failures)
}
}
if (errors.isEmpty()) nextHandler(req) else throw LensFailure(errors)
}
internal fun describe(contractRoot: PathSegments): String = "${pathFn(contractRoot)}${if (pathLenses.isNotEmpty()) "/${pathLenses.joinToString("/")}" else ""}"
}
class ContractRouteSpec0 internal constructor(pathFn: (PathSegments) -> PathSegments, requestParams: List>, body: BodyLens<*>?) : ContractRouteSpec(pathFn, requestParams, body) {
override infix operator fun div(next: String) = ContractRouteSpec0({ it / next }, emptyList(), body)
override infix operator fun div(next: PathLens) = ContractRouteSpec1(pathFn, requestParams, body, next)
}
class ContractRouteSpec1 internal constructor(pathFn: (PathSegments) -> PathSegments, requestParams: List>, body: BodyLens<*>?, val a: PathLens) : ContractRouteSpec(pathFn, requestParams, body, a) {
override infix operator fun div(next: String) = div(Path.fixed(next))
override infix operator fun div(next: PathLens) = ContractRouteSpec2(pathFn, requestParams, body, a, next)
}
class ContractRouteSpec2 internal constructor(pathFn: (PathSegments) -> PathSegments, requestParams: List>, body: BodyLens<*>?, val a: PathLens, val b: PathLens) : ContractRouteSpec(pathFn, requestParams, body, a, b) {
override infix operator fun div(next: String) = div(Path.fixed(next))
override infix operator fun div(next: PathLens) = ContractRouteSpec3(pathFn, requestParams, body, a, b, next)
}
class ContractRouteSpec3 internal constructor(pathFn: (PathSegments) -> PathSegments, requestParams: List>, body: BodyLens<*>?,
val a: PathLens, val b: PathLens, val c: PathLens) : ContractRouteSpec(pathFn, requestParams, body, a, b, c) {
override infix operator fun div(next: String) = div(Path.fixed(next))
override infix operator fun div(next: PathLens) = ContractRouteSpec4(pathFn, requestParams, body, a, b, c, next)
}
class ContractRouteSpec4 internal constructor(pathFn: (PathSegments) -> PathSegments, requestParams: List>, body: BodyLens<*>?,
val a: PathLens, val b: PathLens, val c: PathLens, val d: PathLens) : ContractRouteSpec(pathFn, requestParams, body, a, b, c, d) {
override infix operator fun div(next: String) = throw UnsupportedOperationException("no longer paths!")
override infix operator fun div(next: PathLens) = throw UnsupportedOperationException("no longer paths!")
}