hibiscus/src/main/kotlin/codes/som/hibiscus/api/command/Command.kt

73 lines
2.3 KiB
Kotlin

package codes.som.hibiscus.api.command
import codes.som.hibiscus.api.command.ExecutableCommand.CommandBranch
import codes.som.hibiscus.api.command.parser.ArgumentParser
import java.lang.reflect.ParameterizedType
open class Command(val name: String) {
private val branches = mutableListOf<BranchDeclaration>()
private val aliases = mutableListOf<String>()
fun alias(aliasName: String) {
aliases += aliasName
}
fun branch(branchName: String? = null, handler: Function<*>): BranchDeclaration {
val params = handler.javaClass.genericInterfaces
for (param in params) {
if (param is ParameterizedType) {
val parameterTypes = mutableListOf<Class<*>>()
param.actualTypeArguments
.filterIndexed { index, _ -> index != param.actualTypeArguments.lastIndex }
.filterIsInstance<Class<*>>()
.forEach { parameterTypes += it }
val branchDecl = BranchDeclaration(branchName, handler, parameterTypes.toTypedArray())
branches += branchDecl
return branchDecl
}
}
throw IllegalStateException("Handler function had no generic parameters!")
}
fun buildCommand(): ExecutableCommand {
val command = ExecutableCommand(name, aliases.toTypedArray())
command.branches.addAll(
branches.asSequence()
.map {
CommandBranch(
it.branchName,
it.aliases.toTypedArray(),
it.parameterTypes,
it.handler,
it.typeHints
)
}
)
return command
}
inner class BranchDeclaration internal constructor(
val branchName: String?,
val handler: Function<*>,
val parameterTypes: Array<Class<*>>
) {
internal val aliases = mutableListOf<String>()
internal val typeHints = mutableMapOf<Int, ArgumentParser<*>>()
fun alias(aliasName: String): BranchDeclaration {
aliases += aliasName
return this
}
fun typeHint(index: Int, parser: ArgumentParser<*>): BranchDeclaration {
typeHints[index] = parser
return this
}
}
}