Fix serializing

This commit is contained in:
Him188 2020-05-22 19:40:37 +08:00
parent fe19474c27
commit ef7ea024a0
2 changed files with 39 additions and 15 deletions

View File

@ -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

View File

@ -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