diff --git a/plugin/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt b/plugin/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt index ecb53f1..c6a388b 100644 --- a/plugin/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt +++ b/plugin/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt @@ -26,9 +26,7 @@ object HelloPlugin : Plugin { ) override fun Module.setupDI(config: JsonObject) { - single { - get().decodeFromJsonElement(HelloPluginConfig.serializer(), config["helloPlugin"] ?: return@single null) - } + registerConfig("helloPlugin") } private sealed interface InternalFSMState : State { @@ -43,7 +41,7 @@ object HelloPlugin : Plugin { } override suspend fun BehaviourContextWithFSM.setupBotPlugin(koin: Koin) { - val toPrint = koin.getOrNull() ?.print ?: "Hello :)" + val toPrint = koin.configOrNull() ?.print ?: "Hello :)" logger.d { toPrint } logger.dS { getMe().toString() } onCommand("hello_world") { diff --git a/plugin/src/main/kotlin/dev/inmo/plagubot/KoinExtensions.kt b/plugin/src/main/kotlin/dev/inmo/plagubot/KoinExtensions.kt index d3ed49d..c230e65 100644 --- a/plugin/src/main/kotlin/dev/inmo/plagubot/KoinExtensions.kt +++ b/plugin/src/main/kotlin/dev/inmo/plagubot/KoinExtensions.kt @@ -1,11 +1,59 @@ package dev.inmo.plagubot +import kotlinx.serialization.InternalSerializationApi +import kotlinx.serialization.KSerializer +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.serializer import org.jetbrains.exposed.sql.Database import org.koin.core.Koin +import org.koin.core.module.Module import org.koin.core.scope.Scope +import kotlin.reflect.KClass val Scope.database: Database get() = get() val Koin.database: Database get() = get() + +/** + * Using [single] to register `T` with serializer [configSerializer] + * + * @param optional If passed, absence of [field] in config will lead to null config value in koin. If passed as false + * (default), absence of [field] in config will lead to an error + */ +inline fun Module.registerConfig(configSerializer: KSerializer, field: String?, optional: Boolean = false) { + single { + val fieldValue = get().let { + if (field == null) { + it + } else { + it[field] ?: if (optional) return@single null else error("Unable to take field $field from config") + } + } + get().decodeFromJsonElement(configSerializer, fieldValue) + } +} + +/** + * Using [single] to register config with getting of [serializer] from [kClass] + * + * @param optional If passed, absence of [field] in config will lead to null config value in koin. If passed as false + * (default), absence of [field] in config will lead to an error + */ +@OptIn(InternalSerializationApi::class) +inline fun Module.registerConfig(kClass: KClass, field: String?, optional: Boolean = false) = registerConfig(kClass.serializer(), field, optional) + +/** + * Using [single] to register config with getting of [serializer] from [kClass] + * + * @param optional If passed, absence of [field] in config will lead to null config value in koin. If passed as false + * (default), absence of [field] in config will lead to an error + */ +inline fun Module.registerConfig(field: String?, optional: Boolean = false) = registerConfig(T::class, field, optional) + +inline fun Scope.config() = get() +inline fun Koin.config() = get() +inline fun Scope.configOrNull() = getOrNull() +inline fun Koin.configOrNull() = getOrNull()