rcdbquery/src/main/kotlin/de/pheerai/rcdbquery/dsl/rcdbQueryDsl.kt

91 lines
3.1 KiB
Kotlin

package de.pheerai.rcdbquery.dsl
import de.pheerai.rcdbquery.dataMappings.RcdbParamOption
import de.pheerai.rcdbquery.dataMappings.SearchType
data class RcdbParams(
val multiParams: MultiParams,
val singleParams: SingleParams
) {
fun toStrings(): List<String> {
val multiParamSequence: Sequence<Pair<String, String>> = this.multiParams
.params
.asSequence()
.map { e -> e.key to e.value.joinToString(separator = ",") }
val singleParamSequence: Sequence<Pair<String,String>> = this.singleParams
.params
.asSequence()
.map { it.toPair() }
return singleParamSequence.plus(multiParamSequence)
.map { p -> "${p.first}=${p.second}" }
.toList()
}
}
// In preparation for new handler
sealed class Params<T> {
abstract val params: Map<String, T>
}
class MultiParams(override val params: Map<String, List<String>>) : Params<List<String>>()
class SingleParams(override val params: Map<String, String>) : Params<String>()
class ParamsBuilder {
private val multiParams: MutableMap<String, List<RcdbParamOption<Any>>> = mutableMapOf()
private val singleParams: MutableMap<String, RcdbParamOption<Any>> = mutableMapOf()
fun build() = RcdbParams(buildMulti(), buildSingle())
/**
* Creates the Query Params from this builder.
* If no Search type has been set, this will default to "Coaster"
*/
private fun buildMulti() = multiParams.apply {
putIfAbsent(SearchType.staticParamName, listOf(SearchType.COASTER))
}
.filter { it.value.isNotEmpty() }
.mapValues { e -> e.value.map { o -> o.paramValue.toString() } }
.let { MultiParams(it) }
private fun buildSingle() = singleParams.apply {
// Defaults go here
}
.mapValues { it.toString() }
.let { SingleParams(it) }
operator fun set(paramName: String, options: List<RcdbParamOption<Any>>) {
this.multiParams[paramName] = options
}
operator fun set(paramName: String, option: RcdbParamOption<Any>) {
this.singleParams[paramName] = option
}
fun getSingle(paramName: String) = this.multiParams[paramName] ?: this.singleParams[paramName]
fun getMulti(paramName: String) = this.multiParams[paramName]
fun keys() = this.multiKeys().plus(singleKeys())
private fun multiKeys() = this.multiParams.keys.toSet()
private fun singleKeys() = this.singleParams.keys.toSet()
}
fun rcdbQuery(body: ParamsBuilder.() -> ParamsBuilder) =
RcdbUrlQuery("https://www.rcdb.com/r.htm?", rcdbQueryParams(body)).toString()
data class RcdbUrlQuery(val baseUrl: String, val params: RcdbParams) {
override fun toString(): String {
return params.toStrings()
.joinToString(prefix = baseUrl, separator = "&")
}
}
/**
* Builder for the parameters only (mainly because it might be possilbe in the future to have an API with a POST search object?
*/
fun rcdbQueryParams(body: ParamsBuilder.() -> ParamsBuilder): RcdbParams {
val builder = ParamsBuilder()
builder.body()
return builder.build()
}