mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 15:40:28 +08:00
Fix serializing
This commit is contained in:
parent
fe19474c27
commit
ef7ea024a0
@ -10,12 +10,14 @@
|
||||
package net.mamoe.mirai.console.setting
|
||||
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import net.mamoe.yamlkt.Yaml
|
||||
import net.mamoe.yamlkt.YamlConfiguration
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
internal abstract class AbstractSetting {
|
||||
internal abstract class SettingImpl {
|
||||
|
||||
@JvmField
|
||||
internal var valueList: MutableList<Pair<Value<*>, KProperty<*>>> = mutableListOf()
|
||||
@ -31,15 +33,15 @@ internal abstract class AbstractSetting {
|
||||
internal val kotlinSerializer: KSerializer<Setting> by lazy {
|
||||
object : KSerializer<Setting> {
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = this@AbstractSetting.updaterSerializer.descriptor
|
||||
get() = this@SettingImpl.updaterSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): Setting {
|
||||
this@AbstractSetting.updaterSerializer.deserialize(decoder)
|
||||
return this@AbstractSetting as Setting
|
||||
this@SettingImpl.updaterSerializer.deserialize(decoder)
|
||||
return this@SettingImpl as Setting
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Setting) {
|
||||
this@AbstractSetting.updaterSerializer.serialize(encoder, SettingSerializerMark)
|
||||
this@SettingImpl.updaterSerializer.serialize(encoder, SettingSerializerMark)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -101,20 +103,42 @@ internal class SettingUpdaterSerializer(
|
||||
SettingSerializerMark
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: SettingSerializerMark) = encoder.encodeStructure(descriptor) {
|
||||
instance.valueList.forEachIndexed { index, (value, _) ->
|
||||
@Suppress("UNCHECKED_CAST") // erased, no problem.
|
||||
this.encodeSerializableElement(
|
||||
descriptor,
|
||||
index,
|
||||
value.serializer as KSerializer<Any>,
|
||||
value.value
|
||||
)
|
||||
private val emptyList = emptyList<String>()
|
||||
private val emptyListSerializer = ListSerializer(String.serializer())
|
||||
|
||||
override fun serialize(encoder: Encoder, value: SettingSerializerMark) {
|
||||
if (instance.valueList.isEmpty()) {
|
||||
emptyListSerializer.serialize(encoder, emptyList)
|
||||
} else encoder.encodeStructure(descriptor) {
|
||||
instance.valueList.forEachIndexed { index, (value, _) ->
|
||||
@Suppress("UNCHECKED_CAST") // erased, no problem.
|
||||
this.encodeElementSmart(descriptor, index, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun <T : Any> CompositeEncoder.encodeElementSmart(
|
||||
descriptor: SerialDescriptor,
|
||||
index: Int,
|
||||
value: Value<T>
|
||||
) {
|
||||
when (value.value::class) {
|
||||
String::class -> this.encodeStringElement(descriptor, index, value.value as String)
|
||||
Int::class -> this.encodeIntElement(descriptor, index, value.value as Int)
|
||||
Byte::class -> this.encodeByteElement(descriptor, index, value.value as Byte)
|
||||
Char::class -> this.encodeCharElement(descriptor, index, value.value as Char)
|
||||
Long::class -> this.encodeLongElement(descriptor, index, value.value as Long)
|
||||
Float::class -> this.encodeFloatElement(descriptor, index, value.value as Float)
|
||||
Double::class -> this.encodeDoubleElement(descriptor, index, value.value as Double)
|
||||
Boolean::class -> this.encodeBooleanElement(descriptor, index, value.value as Boolean)
|
||||
else ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
this.encodeSerializableElement(descriptor, index, value.serializer as KSerializer<Any>, value.value)
|
||||
}
|
||||
}
|
||||
|
||||
internal object SettingSerializerMark
|
||||
|
||||
internal val KProperty<*>.serialNameOrPropertyName: String get() = this.findAnnotation<SerialName>()?.value ?: this.name
|
||||
|
@ -22,7 +22,7 @@ typealias SerialName = kotlinx.serialization.SerialName
|
||||
* 配置的基类. 所有配置必须拥有一个无参构造器, 以用于在 [MutableList] 与 [MutableMap] 中动态识别类型
|
||||
*/
|
||||
@Suppress("EXPOSED_SUPER_CLASS")
|
||||
abstract class Setting : AbstractSetting() {
|
||||
abstract class Setting : SettingImpl() {
|
||||
open val serialName: String
|
||||
get() = this::class.findAnnotation<SerialName>()?.value
|
||||
?: this::class.qualifiedName
|
||||
|
Loading…
Reference in New Issue
Block a user