Skip to content

Instantly share code, notes, and snippets.

@libetl libetl/Router.kt
Created Jun 30, 2019

Embed
What would you like to do?
Router
package org.toilelibre.libe
import kotlin.math.pow
import kotlin.reflect.full.companionObject
import kotlin.reflect.full.companionObjectInstance
import kotlin.reflect.full.declaredFunctions
import kotlin.reflect.full.memberProperties
class Router constructor(tableInput: String) {
private val map: Map<List<List<String>>, String>
private val argsCount: Int
init {
map = tableInput.trim().substringAfter('\n').substringAfter('\n')
.split('\n').map { row ->
row.substringBeforeLast('').split('').map {
it.split('|').map { it.trim() }
} to row.substringAfterLast('').trim()
}.toMap()
argsCount = map.keys.first().size + 1
}
inline fun <reified T> valueOf() = T::class.declaredFunctions.find { it.name == "valueOf" }!!
inline fun <reified T,reified R> companionObjectOf(bestValueFor: String) =
T::class.companionObject!!.memberProperties.find { it.name == bestValueFor }!!
.call(T::class.companionObjectInstance) as R
fun bestValueFor(params: Collection<Any?>) =
map.entries.maxBy { entry ->
params.mapIndexed { argNumber, param ->
when {
param?.toString() in entry.key[argNumber] -> 10.toDouble().pow(argsCount - argNumber.toDouble()).toInt()
entry.key[argNumber].all { it.isEmpty() } -> 0
else -> -1
}
}.takeIf { it.all { it >= 0 } }?.sum() ?: -1
}!!.value
inline fun <reified T> `🔀`(vararg params: Any?) = route<T, T>(*params)
inline fun <reified T, reified R> route(vararg params: Any?) =
when {
R::class == String::class -> bestValueFor(params.toList()) as R
T::class.java.isEnum -> valueOf<T>().call(bestValueFor(params.toList())) as R
else -> companionObjectOf<T, R>(bestValueFor(params.toList()))
}
}
package org.toilelibre.libe
import org.junit.Test
import org.toilelibre.libe.RouterTest.Decision.*
import java.security.KeyFactory
import java.security.KeyStore
import kotlin.test.assertEquals
class RouterTest {
@Test
fun noTable() {
assertEquals("", Router("").`🔀`(""))
}
@Test
fun onlyHeader() {
val header =
"""day of the week | time of the day | message
────────────────┼─────────────────┼────────────────────
"""
Router(header).`🔀`<String>()
}
@Test
fun withTexts() {
val messages = Router("""
day of the week | time of the day | message
────────────────┼─────────────────┼────────────────────
Monday │ morning │ Good luck
│ morning │ Good morning
│ afternoon │ Good afternoon
│ evening │ Good evening
│ night │ Good night
Friday │ evening │ Have a good weekend
Saturday │ night │ Have fun
""")
assertEquals("Good luck",
messages.`🔀`("Monday", "morning"))
assertEquals("Good morning",
messages.`🔀`("Wednesday", "morning"))
assertEquals("Good evening",
messages.`🔀`("Saturday", "evening"))
}
enum class Decision {
PASS, REJECT
}
@Test
fun withEnums() {
val exams = Router("""
Maths | Physics | English | Sports | Decision
─────────┼─────────┼─────────┼────────┼─────────
│ │ │ │ $REJECT
$REJECT │ │ │ │ $REJECT
│ $REJECT │ $PASS │ $PASS │ $PASS
$PASS │ $PASS │ │ │ $PASS
""")
assertEquals(REJECT,
exams.`🔀`(REJECT, null, null, null))
assertEquals(REJECT,
exams.`🔀`(REJECT, PASS, PASS, PASS))
assertEquals(PASS,
exams.`🔀`(PASS, REJECT, PASS, PASS))
assertEquals(REJECT,
exams.`🔀`(null, null, null, null))
}
companion object {
val RSA = KeyFactory.getInstance("RSA")!!
val JKS = KeyStore.getInstance("JKS")!!
val PKCS12 = KeyStore.getInstance("PKCS12")!!
}
@Test
fun useCompanionObject() {
val router = Router("""
arch │ hasJava │ has.NET │ choose
───────────┼─────────┼─────────┼─────────
│ │ │ RSA
│ yes │ │ JKS
win │ │ │ PKCS12
win|linux │ │ yes │ PKCS12
""")
assertEquals(RSA,
router.route<RouterTest, KeyFactory>("linux", "no", "no"))
assertEquals(PKCS12,
router.route<RouterTest, KeyStore>("linux", "no", "yes"))
assertEquals(PKCS12,
router.route<RouterTest, KeyStore>("win", "no", "yes"))
assertEquals(PKCS12,
router.route<RouterTest, KeyStore>("win", "yes", "no"))
assertEquals(JKS,
router.route<RouterTest, KeyStore>("linux", "yes", "no"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.