First semi-proper DSL-like syntax

- Native builds to compile now
 - Add Arvm 32 bit target
 - Add Jvm main class for test runs
This commit is contained in:
Oliver Rümpelein 2020-04-08 15:56:19 +02:00
parent e4c66567ea
commit cc703d5554
16 changed files with 241 additions and 68 deletions

View file

@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
plugins { plugins {
id("org.jetbrains.kotlin.multiplatform") id("org.jetbrains.kotlin.multiplatform")
} }
@ -28,8 +30,18 @@ kotlin {
// For Linux, should be changed to e.g. linuxX64 // For Linux, should be changed to e.g. linuxX64
// For MacOS, should be changed to e.g. macosX64 // For MacOS, should be changed to e.g. macosX64
// For Windows, should be changed to e.g. mingwX64 // For Windows, should be changed to e.g. mingwX64
linuxX64("linuxX64") linuxX64("linuxX64")
linuxArm64("linuxAArch") linuxArm64("linuxArm64")
linuxArm32Hfp("linuxArm32")
targets.withType<KotlinNativeTarget> {
binaries {
executable {
entryPoint("de.pheerai.rcdbquery.main")
}
}
}
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
@ -54,9 +66,6 @@ kotlin {
} }
} }
getByName("jsMain") { getByName("jsMain") {
dependencies {
implementation(kotlin("stdlib-js"))
}
} }
getByName("jsTest") { getByName("jsTest") {
dependencies { dependencies {
@ -67,9 +76,12 @@ kotlin {
} }
getByName("linuxX64Test") { getByName("linuxX64Test") {
} }
getByName("linuxAArchMain") { getByName("linuxArm64Main") {
} }
getByName("linuxAArchTest") { getByName("linuxArm64Test") {
}
all {
languageSettings.enableLanguageFeature("InlineClasses")
} }
} }
} }

View file

@ -1,5 +1,8 @@
package de.pheerai.rcdbquery package de.pheerai.rcdbquery
import de.pheerai.rcdbquery.dataMappings.*
import de.pheerai.rcdbquery.dsl.*
expect class Sample() { expect class Sample() {
fun checkMe(): Int fun checkMe(): Int
} }
@ -9,3 +12,20 @@ expect object Platform {
} }
fun hello(): String = "Hello from ${Platform.name}" fun hello(): String = "Hello from ${Platform.name}"
fun generateQueryUrl() = rcdbQuery {
searchFor(SearchType.COASTER)
vendors(
Vendor.INTAMIN,
Vendor.MACK
)
sortBy(
Order.MANUFACTURER,
Order.INVERSIONS
)
custom(
"foo",
createRcdbParam(paramId = 12),
createRcdbParam(paramId = 24)
)
}

View file

@ -0,0 +1,16 @@
package de.pheerai.rcdbquery.dataMappings
enum class Order(
override val prettyName: String,
override val fullName: String,
override val paramId: Int
) : RcdbParamOption {
MANUFACTURER("Manufacturer", 30),
INVERSIONS("Inversion", "Number of inversions", 24);
constructor(name: String, paramId: Int) : this(name, name, paramId)
companion object {
const val staticParamName = "order"
}
}

View file

@ -0,0 +1,20 @@
package de.pheerai.rcdbquery.dataMappings
interface RcdbParamOption {
val prettyName: String
val fullName: String
val paramId: Int
}
fun createRcdbParam(
prettyName: String = "",
fullName:String = "",
paramId: Int = -1
) : RcdbParamOption = object : RcdbParamOption {
override val prettyName: String
get() = prettyName
override val fullName: String
get() = fullName
override val paramId: Int
get() = paramId
}

View file

@ -0,0 +1,8 @@
package de.pheerai.rcdbquery.dataMappings
data class RcdbQueryParam<out T : RcdbParamOption>(val paramName: String, val paramOptions: List<T>)
data class RcdbQueryParamBuilder<T : RcdbParamOption>(var paramName: String, val paramOption: MutableList<T>) {
fun append(option: T) {
this.paramOption.add(option)
}
}

View file

@ -0,0 +1,14 @@
package de.pheerai.rcdbquery.dataMappings
enum class SearchType(
override val prettyName: String,
override val fullName: String,
override val paramId: Int
) : RcdbParamOption {
COASTER("Coaster", "Search for Roller Coaster", 2)
;
companion object {
const val staticParamName = "ot"
}
}

View file

@ -1,6 +1,10 @@
package de.pheerai.rcdbquery.dataMappings package de.pheerai.rcdbquery.dataMappings
enum class Vendor(val prettyName: String, val fullName: String, val queryId: Int) { enum class Vendor(
override val prettyName: String,
override val fullName: String,
override val paramId: Int
) : RcdbParamOption {
INTAMIN("Intamin", "Intamin Amusement Rides", 6837), INTAMIN("Intamin", "Intamin Amusement Rides", 6837),
VEKOMA("Vekoma", 6836), VEKOMA("Vekoma", 6836),
MACK("Mack Rides", "Mack Rides GmbH & Co KG", 6856), MACK("Mack Rides", "Mack Rides GmbH & Co KG", 6856),
@ -14,16 +18,11 @@ enum class Vendor(val prettyName: String, val fullName: String, val queryId: Int
RMC("RMC", "Rocky Mountain Construction", 10583) RMC("RMC", "Rocky Mountain Construction", 10583)
; ;
constructor(name: String, queryId: Int) : this(name, name, queryId) constructor(name: String, paramId: Int) : this(name, name, paramId)
val queryParam
get() = "${queryParamName}=${this.queryId}"
companion object { companion object {
const val queryParamName = "mk" const val staticParamName = "mk"
fun createQueryParam(vararg vendors: Vendor) = vendors.joinToString("&") { it.queryParam }
fun createQueryParam(name: String): String = createQueryParam(*searchByName(name).toTypedArray())
fun getByName(name: String): Vendor? = values().firstOrNull { it.prettyName == name } fun getByName(name: String): Vendor? = values().firstOrNull { it.prettyName == name }
fun searchByName(name: String): List<Vendor> { fun searchByName(name: String): List<Vendor> {
val searchName = name.toLowerCase() val searchName = name.toLowerCase()

View file

@ -0,0 +1,74 @@
package de.pheerai.rcdbquery.dsl
import de.pheerai.rcdbquery.dataMappings.*
inline class RcdbQueryParams(val params: Map<String, List<Int>>)
class RcdbQueryParamsBuilder {
// TODO: Somewhat wrap away, then use param of one option.
private val params: MutableMap<String, List<RcdbParamOption>> = mutableMapOf()
fun build() = RcdbQueryParams(
params
.filter { it.value.isNotEmpty() }
.mapValues { e -> e.value.map { o -> o.paramId } }
)
operator fun set(paramName: String, options: List<RcdbParamOption>) {
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
}
}
private fun List<RcdbParamOption>?.append(options: List<RcdbParamOption>) = this?.toMutableList()?.also { it.addAll(options) } ?: options
}
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: Even better typing (usage of
* ```
* vendors {
* vekoma()
* intamin()
* of(Vendors.PRESTON_AND_BARBIERI)
* }
* ```
* instead.
* Maybe use inline class for MutableList / List?
*/
fun RcdbQueryParamsBuilder.vendors(vendors: List<Vendor>) = apply { this[Vendor.staticParamName] = vendors }
fun RcdbQueryParamsBuilder.vendors(vararg vendors: Vendor) = this.vendors(vendors.asList())
fun RcdbQueryParamsBuilder.sortBy(orders: List<Order>) = apply {
this[Order.staticParamName] =orders
}
fun RcdbQueryParamsBuilder.sortBy(vararg orders: Order) = this.sortBy(orders.asList())
fun RcdbQueryParamsBuilder.searchFor(searchType: SearchType) =
apply { this[SearchType.staticParamName] = listOf(searchType) }
fun RcdbQueryParamsBuilder.custom(paramName: String, values: List<RcdbParamOption>) = apply { this[paramName] = values }
fun RcdbQueryParamsBuilder.custom(paramName: String, vararg values: RcdbParamOption) = apply { this[paramName] = values.asList() }

View file

@ -1,52 +0,0 @@
package de.pheerai.rcdbquery.dataMappings
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
class VendorTest {
@Test
fun testQueryParam() {
assertEquals(
"mk=6837",
Vendor.INTAMIN.queryParam
)
}
@Test
fun testQueryParamsGeneration() {
assertEquals(
"mk=6837&mk=6836",
Vendor.createQueryParam(Vendor.INTAMIN, Vendor.VEKOMA),
"Generation by Enum lookup failed."
)
assertEquals(
"mk=6836&mk=6856&mk=6905",
Vendor.createQueryParam("Ma"),
"Generation by name search failed."
)
}
@Test
fun testGetByName() {
assertEquals(
Vendor.INTAMIN,
Vendor.getByName("Intamin")
)
assertNull(
Vendor.getByName("asdf anjfejasdnf njnas")
)
}
@Test
fun testSearchByName() {
assertEquals(
listOf(Vendor.VEKOMA, Vendor.MACK, Vendor.MAURER),
Vendor.searchByName("ma")
)
assertEquals(
listOf(),
Vendor.searchByName("asdf anjfejasdnf njnas")
)
}
}

View file

@ -0,0 +1,26 @@
package de.pheerai.rcdbquery.dsl
import de.pheerai.rcdbquery.dataMappings.Order
import de.pheerai.rcdbquery.dataMappings.Vendor
import kotlin.test.Test
import kotlin.test.assertEquals
class RcdbQueryDslTest {
@Test
fun testQueryParamBuilder() {
assertEquals(
"https://www.rcdb.com/r.htm?mk=6836,6856,6905&order=24,30",
rcdbQuery {
vendors(
Vendor.VEKOMA,
Vendor.MACK,
Vendor.MAURER
)
sortBy(
Order.INVERSIONS,
Order.MANUFACTURER
)
}
)
}
}

View file

@ -7,3 +7,7 @@ actual class Sample {
actual object Platform { actual object Platform {
actual val name: String = "JVM" actual val name: String = "JVM"
} }
fun main() {
print(generateQueryUrl())
}

View file

@ -7,3 +7,7 @@ actual class Sample {
actual object Platform { actual object Platform {
actual val name: String = "Native" actual val name: String = "Native"
} }
fun main() {
println(generateQueryUrl())
}

View file

@ -0,0 +1,13 @@
package de.pheerai.rcdbquery
actual class Sample {
actual fun checkMe() = 7
}
actual object Platform {
actual val name: String = "Native"
}
fun main() {
println(generateQueryUrl())
}

View file

@ -0,0 +1,11 @@
package de.pheerai.rcdbquery
import kotlin.test.Test
import kotlin.test.assertTrue
class SampleTestsNative {
@Test
fun testHello() {
assertTrue("Native" in hello())
}
}

View file

@ -7,3 +7,7 @@ actual class Sample {
actual object Platform { actual object Platform {
actual val name: String = "Native" actual val name: String = "Native"
} }
fun main() {
println(generateQueryUrl())
}