Migrate signatures parsers to Kotlin

This commit is contained in:
2020-03-07 23:00:33 +01:00
parent e14eb17aa6
commit 945df28a29
5 changed files with 99 additions and 1 deletions

View File

@@ -0,0 +1,21 @@
package io.smnp.data.signature
import io.smnp.data.model.Value
class ArgumentsList(val isValid: Boolean, val arguments: List<Value>) {
operator fun get(index: Int) = arguments[index]
fun toArray() = arguments.toTypedArray()
override fun toString() = if(isValid) "valid($arguments)" else "invalid"
companion object {
fun valid(arguments: List<Value>): ArgumentsList {
return ArgumentsList(true, arguments)
}
fun invalid(): ArgumentsList {
return ArgumentsList(false, emptyList())
}
}
}

View File

@@ -3,7 +3,7 @@ package io.smnp.data.signature
import io.smnp.data.enumeration.DataType
import io.smnp.data.model.Value
class Matcher(val type: DataType?, val matcher: (Value) -> Boolean, val string: String) {
class Matcher(val type: DataType?, private val matcher: (Value) -> Boolean, private val string: String, val optional: Boolean = false) {
fun match(value: Value): Boolean =
(type != null && type == value.type && matcher(value)) || (type == null) && matcher(value)
@@ -31,6 +31,10 @@ class Matcher(val type: DataType?, val matcher: (Value) -> Boolean, val string:
override fun toString() = string
companion object {
fun optional(matcher: Matcher): Matcher {
return Matcher(matcher.type, matcher.matcher, "${matcher.string}?", true)
}
fun mapOfMatchers(keyMatchers: List<Matcher>, valueMatchers: List<Matcher>): Matcher {
return Matcher(
DataType.MAP,

View File

@@ -0,0 +1,17 @@
package io.smnp.data.signature
import io.smnp.data.model.Value
interface Signature {
fun parse(arguments: List<Value>): ArgumentsList
companion object {
fun simple(vararg signature: Matcher): Signature {
return SimpleSignature(*signature)
}
fun vararg(varargMatcher: Matcher, vararg signature: Matcher): Signature {
return VarargSignature(varargMatcher, *signature)
}
}
}

View File

@@ -0,0 +1,15 @@
package io.smnp.data.signature
import io.smnp.data.model.Value
class SimpleSignature(private vararg val signature: Matcher) : Signature {
override fun parse(arguments: List<Value>): ArgumentsList {
if (arguments.size > signature.size || arguments.size < signature.count { !it.optional }) {
return ArgumentsList.invalid()
}
return ArgumentsList(signature.zip(arguments).all { (matcher, argument) -> matcher.match(argument) }, arguments)
}
override fun toString() = "(${signature.joinToString(", ")})"
}

View File

@@ -0,0 +1,41 @@
package io.smnp.data.signature
import io.smnp.data.model.Value
class VarargSignature(private val varargMatcher: Matcher, private vararg val signature: Matcher) : Signature {
override fun parse(arguments: List<Value>): ArgumentsList {
if ((arrayListOf(varargMatcher) + signature).any { it.optional }) {
throw RuntimeException("Vararg signature does not support optional arguments")
}
if (signature.size > arguments.size) {
return ArgumentsList.invalid()
}
for (i in signature.indices) {
if (!signature[i].match(arguments[i])) {
return ArgumentsList.invalid()
}
}
for (i in signature.size until arguments.size) {
if (!varargMatcher.match(arguments[i])) {
return ArgumentsList.invalid()
}
}
return ArgumentsList.valid(
arguments.subList(0, signature.size) + listOf(
Value.list(
arguments.subList(
signature.size,
arguments.size
)
)
)
)
}
override fun toString() =
"(${signature.joinToString(", ")}${if (signature.isNotEmpty()) ", " else ""}...$varargMatcher)"
}