io.github.freya022.botcommands.internal.commands.application.MutableApplicationCommandMap.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of BotCommands Show documentation
Show all versions of BotCommands Show documentation
A Kotlin-first (and Java) framework that makes creating Discord bots a piece of cake, using the JDA library.
package io.github.freya022.botcommands.internal.commands.application
import io.github.freya022.botcommands.api.commands.CommandPath
import io.github.freya022.botcommands.api.commands.application.ApplicationCommandMap
import io.github.freya022.botcommands.api.core.utils.enumMapOf
import io.github.freya022.botcommands.internal.commands.application.context.message.MessageCommandInfo
import io.github.freya022.botcommands.internal.commands.application.context.user.UserCommandInfo
import io.github.freya022.botcommands.internal.commands.application.slash.TopLevelSlashCommandInfo
import net.dv8tion.jda.api.interactions.commands.Command
import java.util.*
import java.util.function.Function
import net.dv8tion.jda.api.interactions.commands.Command.Type as CommandType
internal class MutableApplicationCommandMap internal constructor(
private val rawTypeMap: MutableMap> = Collections.synchronizedMap(enumMapOf())
) : ApplicationCommandMap() {
internal class UnmodifiableApplicationCommandMap(private val map: ApplicationCommandMap) : ApplicationCommandMap() {
override fun getTypeMap(type: Command.Type): CommandMap =
map.getTypeMap(type).toUnmodifiableMap()
}
@Suppress("UNCHECKED_CAST")
internal object EmptyApplicationCommandMap : ApplicationCommandMap() {
override fun getTypeMap(type: Command.Type): CommandMap =
EmptyCommandMap as CommandMap
}
internal fun computeIfAbsent(
type: CommandType,
path: CommandPath,
mappingFunction: Function
): T = getTypeMap(type).computeIfAbsent(path, mappingFunction)
internal fun put(type: CommandType, path: CommandPath, value: T): T? = getTypeMap(type).put(path, value)
@Suppress("UNCHECKED_CAST")
override fun getTypeMap(type: CommandType): MutableCommandMap {
return rawTypeMap.computeIfAbsent(type) { MutableCommandMap() } as MutableCommandMap
}
internal companion object {
@JvmStatic
val EMPTY_MAP: ApplicationCommandMap = EmptyApplicationCommandMap
internal fun fromCommandList(guildApplicationCommands: Collection) = MutableApplicationCommandMap().also { map ->
for (info in guildApplicationCommands) {
val type = when (info) {
is MessageCommandInfo -> CommandType.MESSAGE
is UserCommandInfo -> CommandType.USER
is TopLevelSlashCommandInfo -> CommandType.SLASH
else -> throw IllegalArgumentException("Unknown application command info type: " + info.javaClass.name)
}
val typeMap = map.getTypeMap(type)
when (info) {
is UserCommandInfo, is MessageCommandInfo -> typeMap[info.path] = info
is TopLevelSlashCommandInfo -> {
if (info.isTopLevelCommandOnly()) {
typeMap[info.path] = info
} else {
info.subcommandGroups.values.forEach { groupInfo ->
groupInfo.subcommands.values.forEach {
typeMap[it.path] = it
}
}
info.subcommands.values.forEach {
typeMap[it.path] = it
}
}
}
else -> throw IllegalArgumentException("Unknown application command info type: " + info.javaClass.name)
}
}
}
}
}
internal fun ApplicationCommandMap.toUnmodifiableMap(): ApplicationCommandMap {
if (this is MutableApplicationCommandMap.UnmodifiableApplicationCommandMap) return this
return MutableApplicationCommandMap.UnmodifiableApplicationCommandMap(this)
}