155 lines
5.4 KiB
Kotlin
155 lines
5.4 KiB
Kotlin
package de.pheerai.rcdbquery.dsl
|
|
|
|
import de.pheerai.rcdbquery.dataMappings.*
|
|
|
|
inline class RcdbQueryParams(val params: Map<String, List<String>>)
|
|
class RcdbQueryParamsBuilder {
|
|
// TODO: Make way for single-valued params as well
|
|
private val params: MutableMap<String, List<RcdbParamOption<Any>>> = mutableMapOf()
|
|
|
|
// TODO: Validate that search type is set
|
|
fun build() = RcdbQueryParams(
|
|
params
|
|
.filter { it.value.isNotEmpty() }
|
|
.mapValues { e -> e.value.map { o -> o.paramValue.toString() } }
|
|
)
|
|
|
|
operator fun set(paramName: String, options: List<RcdbParamOption<Any>>) {
|
|
when (paramName) {
|
|
"order" -> if (this.params.containsKey(paramName)) {
|
|
this.params[paramName] = this.params[paramName].append(options)
|
|
} else {
|
|
this.params[paramName] = options
|
|
}
|
|
else -> this.params[paramName] = options
|
|
}
|
|
}
|
|
|
|
operator fun get(paramName: String) = this.params[paramName]
|
|
|
|
private fun List<RcdbParamOption<Any>>?.append(options: List<RcdbParamOption<Any>>) =
|
|
this?.toMutableList()?.also { it.addAll(options) } ?: options
|
|
|
|
fun keys() = this.params.keys.toSet()
|
|
}
|
|
|
|
fun rcdbQuery(body: RcdbQueryParamsBuilder.() -> RcdbQueryParamsBuilder) =
|
|
RcdbUrlQuery("https://www.rcdb.com/r.htm?", rcdbQueryParams(body)).toString()
|
|
|
|
data class RcdbUrlQuery(val baseUrl: String, val params: RcdbQueryParams) {
|
|
override fun toString(): String {
|
|
return params.params
|
|
.asSequence()
|
|
.map { e -> e.key to e.value.joinToString(separator = ",") }
|
|
.map { p -> "${p.first}=${p.second}" }
|
|
.joinToString(prefix = baseUrl, separator = "&")
|
|
}
|
|
}
|
|
|
|
fun rcdbQueryParams(body: RcdbQueryParamsBuilder.() -> RcdbQueryParamsBuilder): RcdbQueryParams {
|
|
val builder = RcdbQueryParamsBuilder()
|
|
builder.body()
|
|
return builder.build()
|
|
}
|
|
|
|
// TODO: Find way to only have one generic parameter
|
|
sealed class RcdbParamOptionBuilder<out U : Any, T : RcdbParamOption<U>> {
|
|
private val paramList: MutableList<T> = mutableListOf()
|
|
|
|
open fun add(param: T): RcdbParamOptionBuilder<U, T> {
|
|
paramList.add(param)
|
|
return this
|
|
}
|
|
|
|
fun build() = paramList.toList()
|
|
}
|
|
|
|
//region Vendors
|
|
class VendorBuilder : RcdbParamOptionBuilder<Int, Vendor>() {
|
|
override fun add(param: Vendor): VendorBuilder {
|
|
super.add(param)
|
|
return this
|
|
}
|
|
}
|
|
|
|
fun RcdbQueryParamsBuilder.vendors(body: VendorBuilder.() -> VendorBuilder): RcdbQueryParamsBuilder {
|
|
val builder = VendorBuilder()
|
|
builder.body()
|
|
this[Vendor.staticParamName] = builder.build()
|
|
return this
|
|
}
|
|
|
|
fun VendorBuilder.of(vendor: Vendor) = this.add(vendor)
|
|
fun VendorBuilder.vekoma() = this.add(Vendor.VEKOMA)
|
|
fun VendorBuilder.intamin() = this.add(Vendor.INTAMIN)
|
|
fun VendorBuilder.mack() = this.add(Vendor.MACK)
|
|
fun VendorBuilder.bandm() = this.add(Vendor.B_AND_M)
|
|
fun VendorBuilder.gerstlauer() = this.add(Vendor.GERSTLAUER)
|
|
//endregion
|
|
|
|
//region Order
|
|
class OrderBuilder : RcdbParamOptionBuilder<Int, Order>() {
|
|
override fun add(param: Order): OrderBuilder {
|
|
super.add(param)
|
|
return this
|
|
}
|
|
}
|
|
|
|
fun RcdbQueryParamsBuilder.sortBy(body: OrderBuilder.() -> OrderBuilder): RcdbQueryParamsBuilder {
|
|
val builder = OrderBuilder()
|
|
builder.body()
|
|
this[Order.staticParamName] = builder.build()
|
|
return this
|
|
}
|
|
|
|
fun OrderBuilder.of(order: Order) = this.add(order)
|
|
fun OrderBuilder.manufacturer() = this.add(Order.MANUFACTURER)
|
|
fun OrderBuilder.inversion() = this.add(Order.INVERSIONS)
|
|
//endregion
|
|
|
|
//region Search type
|
|
fun RcdbQueryParamsBuilder.searchFor(searchType: SearchType) {
|
|
if (SearchType.staticParamName !in this.keys()) {
|
|
this[SearchType.staticParamName] = listOf(searchType)
|
|
} else {
|
|
error(
|
|
"""Only one search type must ever be set
|
|
| Old type: ${this[SearchType.staticParamName]!![0].prettyName}
|
|
| New type: ${searchType.prettyName}""".trimMargin()
|
|
)
|
|
}
|
|
}
|
|
//endregion
|
|
|
|
//region Search Term
|
|
fun RcdbQueryParamsBuilder.searchTerm(term: String) {
|
|
if (SearchTerm.staticParamName !in this.keys()) {
|
|
this[SearchTerm.staticParamName] = listOf(SearchTerm(term))
|
|
} else {
|
|
error(
|
|
"""Only one search term must ever be set
|
|
| Old term: ${this[SearchTerm.staticParamName]!![0].paramValue}
|
|
| New term: $term""".trimMargin()
|
|
)
|
|
}
|
|
}
|
|
//endregion
|
|
|
|
//region Unknown fields
|
|
@Suppress("unused")
|
|
@Deprecated(
|
|
"The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)",
|
|
ReplaceWith("sortBy"), DeprecationLevel.ERROR
|
|
)
|
|
fun RcdbQueryParamsBuilder.extraColumns(orders: List<Order>): Nothing =
|
|
error("The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)")
|
|
|
|
@Suppress("unused")
|
|
@Deprecated(
|
|
"The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)",
|
|
ReplaceWith("sortBy"), DeprecationLevel.ERROR
|
|
)
|
|
fun RcdbQueryParamsBuilder.extraColumns(vararg orders: Order): Nothing =
|
|
error("The parameter for extra columns has not yet been discovered (if it even exists). Use multiple values in the `sortBy` param instead (first values take sorting precedence)")
|
|
//endregion
|