From b3711f965b6cd9f02791186d1e26c37e1a31047e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20R=C3=BCmpelein?= Date: Fri, 1 May 2020 13:49:55 +0200 Subject: [PATCH] Prepared single parameter handling. --- .../rcdbquery/dataMappings/Classification.kt | 4 +- .../pheerai/rcdbquery/dataMappings/Order.kt | 4 +- .../de/pheerai/rcdbquery/dataMappings/Page.kt | 6 +- .../rcdbquery/dataMappings/SearchTerm.kt | 6 +- .../rcdbquery/dataMappings/SearchType.kt | 6 +- .../rcdbquery/dataMappings/StartsWith.kt | 6 +- .../pheerai/rcdbquery/dataMappings/Status.kt | 4 +- .../pheerai/rcdbquery/dataMappings/Vendor.kt | 4 +- .../rcdbquery/dataMappings/unknownParams.kt | 6 +- .../de/pheerai/rcdbquery/dsl/rcdbQueryDsl.kt | 62 +++++++++++++------ 10 files changed, 67 insertions(+), 41 deletions(-) diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Classification.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Classification.kt index 318ebca..f9e226e 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Classification.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Classification.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder enum class Classification( override val prettyName: String, @@ -19,7 +19,7 @@ enum class Classification( } } -fun MultiParamsBuilder.classification(body: ClassificationBuilder.() -> ClassificationBuilder): MultiParamsBuilder { +fun ParamsBuilder.classification(body: ClassificationBuilder.() -> ClassificationBuilder): ParamsBuilder { val builder = ClassificationBuilder() builder.body() this[Classification.staticParamName] = builder.build() diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Order.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Order.kt index bb6ed22..f8d42a3 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Order.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Order.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder @Suppress("unused") enum class Order( @@ -51,7 +51,7 @@ enum class Order( } } -fun MultiParamsBuilder.sortBy(body: OrderBuilder.() -> OrderBuilder): MultiParamsBuilder { +fun ParamsBuilder.sortBy(body: OrderBuilder.() -> OrderBuilder): ParamsBuilder { val builder = OrderBuilder() builder.body() this[Order.staticParamName] = builder.build() diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Page.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Page.kt index e73423e..1429845 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Page.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Page.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder class Page(override val paramValue: Int) : RcdbParamOption { override val fullName = "The page to show" @@ -11,12 +11,12 @@ class Page(override val paramValue: Int) : RcdbParamOption { } } -fun MultiParamsBuilder.page(page: Int) = if (Page.staticParamName !in this.keys()) { +fun ParamsBuilder.page(page: Int) = if (Page.staticParamName !in this.keys()) { also { this[Page.staticParamName] = listOf(Page(page)) } } else { error( """Only one page must be given! - | Old page: ${this[Page.staticParamName]!![0].paramValue} + | Old page: ${this.getMulti(Page.staticParamName)!![0].paramValue} | New page: $page """.trimMargin() ) diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchTerm.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchTerm.kt index 48e98c6..5caecaa 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchTerm.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchTerm.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder class SearchTerm(override val paramValue: String) : RcdbParamOption { override val prettyName = "Search Term" @@ -11,13 +11,13 @@ class SearchTerm(override val paramValue: String) : RcdbParamOption { } } -fun MultiParamsBuilder.searchTerm(term: String) = +fun ParamsBuilder.searchTerm(term: String) = if (SearchTerm.staticParamName !in this.keys()) { also { this[SearchTerm.staticParamName] = listOf(SearchTerm(term)) } } else { error( """Only one search term must ever be set - | Old term: ${this[SearchTerm.staticParamName]!![0].paramValue} + | Old term: ${this.getMulti(SearchTerm.staticParamName)!![0].paramValue} | New term: $term""".trimMargin() ) } diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchType.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchType.kt index 8eb4bf1..c3de8e4 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchType.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/SearchType.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder @Suppress("unused") enum class SearchType( @@ -19,13 +19,13 @@ enum class SearchType( } } -fun MultiParamsBuilder.searchType(searchType: SearchType) = +fun ParamsBuilder.searchType(searchType: SearchType) = if (SearchType.staticParamName !in this.keys()) { also { this[SearchType.staticParamName] = listOf(searchType) } } else { error( """Only one search type must ever be set - | Old type: ${this[SearchType.staticParamName]!![0].prettyName} + | Old type: ${this.getMulti(SearchType.staticParamName)!![0].prettyName} | New type: ${searchType.prettyName}""".trimMargin() ) } diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/StartsWith.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/StartsWith.kt index 8995d1c..196b969 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/StartsWith.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/StartsWith.kt @@ -2,7 +2,7 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder class StartsWith(override val paramValue: String) : RcdbParamOption { override val prettyName = "Starts with" @@ -13,12 +13,12 @@ class StartsWith(override val paramValue: String) : RcdbParamOption { } } -fun MultiParamsBuilder.startsWith(term: String) = if (StartsWith.staticParamName !in this.keys()) { +fun ParamsBuilder.startsWith(term: String) = if (StartsWith.staticParamName !in this.keys()) { also { this[StartsWith.staticParamName] = listOf(StartsWith(term)) } } else { error( """Only one starts with term must ever be set - | Old term: ${this[StartsWith.staticParamName]!![0].paramValue} + | Old term: ${this.getMulti(StartsWith.staticParamName)!![0].paramValue} | New term: $term""".trimMargin() ) } diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Status.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Status.kt index 2f1dc39..e1eb85f 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Status.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Status.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder @Suppress("unused") enum class Status( @@ -29,7 +29,7 @@ enum class Status( } } -fun MultiParamsBuilder.status(body: StatusBuilder.() -> StatusBuilder): MultiParamsBuilder { +fun ParamsBuilder.status(body: StatusBuilder.() -> StatusBuilder): ParamsBuilder { val builder = StatusBuilder() builder.body() this[Status.staticParamName] = builder.build() diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Vendor.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Vendor.kt index ed03f94..15d6c41 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Vendor.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/Vendor.kt @@ -1,6 +1,6 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder @Suppress("unused") enum class Vendor( @@ -254,7 +254,7 @@ enum class Vendor( } } -fun MultiParamsBuilder.vendors(body: VendorBuilder.() -> VendorBuilder): MultiParamsBuilder { +fun ParamsBuilder.vendors(body: VendorBuilder.() -> VendorBuilder): ParamsBuilder { val builder = VendorBuilder() builder.body() this[Vendor.staticParamName] = builder.build() diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/unknownParams.kt b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/unknownParams.kt index de2fb9a..583ae5c 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/unknownParams.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dataMappings/unknownParams.kt @@ -1,13 +1,13 @@ package de.pheerai.rcdbquery.dataMappings -import de.pheerai.rcdbquery.dsl.MultiParamsBuilder +import de.pheerai.rcdbquery.dsl.ParamsBuilder @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 MultiParamsBuilder.extraColumns(orders: List): Nothing = +fun ParamsBuilder.extraColumns(orders: List): 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") @@ -15,5 +15,5 @@ fun MultiParamsBuilder.extraColumns(orders: List): Nothing = "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 MultiParamsBuilder.extraColumns(vararg orders: Order): Nothing = +fun ParamsBuilder.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)") diff --git a/src/main/kotlin/de/pheerai/rcdbquery/dsl/rcdbQueryDsl.kt b/src/main/kotlin/de/pheerai/rcdbquery/dsl/rcdbQueryDsl.kt index 095ee55..b74d278 100644 --- a/src/main/kotlin/de/pheerai/rcdbquery/dsl/rcdbQueryDsl.kt +++ b/src/main/kotlin/de/pheerai/rcdbquery/dsl/rcdbQueryDsl.kt @@ -3,6 +3,25 @@ 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 { + val multiParamSequence: Sequence> = this.multiParams + .params + .asSequence() + .map { e -> e.key to e.value.joinToString(separator = ",") } + val singleParamSequence: Sequence> = 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 { abstract val params: Map @@ -11,44 +30,51 @@ sealed class Params { class MultiParams(override val params: Map>) : Params>() class SingleParams(override val params: Map) : Params() -interface ParamsBuilder { - fun build(): T - operator fun set(paramName: String, options: U) -} - -class MultiParamsBuilder : ParamsBuilder>> { +class ParamsBuilder { private val multiParams: MutableMap>> = mutableMapOf() + private val singleParams: MutableMap> = 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" */ - override fun build() = multiParams.apply { + 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) } - override operator fun set(paramName: String, options: List>) { + operator fun set(paramName: String, options: List>) { this.multiParams[paramName] = options } - operator fun get(paramName: String) = this.multiParams[paramName] + operator fun set(paramName: String, option: RcdbParamOption) { + this.singleParams[paramName] = option + } - fun keys() = this.multiParams.keys.toSet() + 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: MultiParamsBuilder.() -> MultiParamsBuilder) = +fun rcdbQuery(body: ParamsBuilder.() -> ParamsBuilder) = RcdbUrlQuery("https://www.rcdb.com/r.htm?", rcdbQueryParams(body)).toString() -data class RcdbUrlQuery(val baseUrl: String, val params: MultiParams) { +data class RcdbUrlQuery(val baseUrl: String, val params: RcdbParams) { override fun toString(): String { - return params.params - .asSequence() - .map { e -> e.key to e.value.joinToString(separator = ",") } - .map { p -> "${p.first}=${p.second}" } + return params.toStrings() .joinToString(prefix = baseUrl, separator = "&") } } @@ -56,8 +82,8 @@ data class RcdbUrlQuery(val baseUrl: String, val params: MultiParams) { /** * 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: MultiParamsBuilder.() -> MultiParamsBuilder): MultiParams { - val builder = MultiParamsBuilder() +fun rcdbQueryParams(body: ParamsBuilder.() -> ParamsBuilder): RcdbParams { + val builder = ParamsBuilder() builder.body() return builder.build() }