commonMain.Serialization.kt Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
@file:JvmName("SerializationKt_common")
package net.mamoe.mirai.utils
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlin.jvm.JvmName
public fun SerialDescriptor.copy(newName: String): SerialDescriptor =
buildClassSerialDescriptor(newName) { takeElementsFrom(this@copy) }
@OptIn(ExperimentalSerializationApi::class) // bad but there is no other solution
public fun ClassSerialDescriptorBuilder.takeElementsFrom(descriptor: SerialDescriptor) {
with(descriptor) {
repeat(descriptor.elementsCount) { index ->
element(
elementName = getElementName(index),
descriptor = getElementDescriptor(index),
annotations = getElementAnnotations(index),
isOptional = isElementOptional(index),
)
}
}
}
public inline fun KSerializer.map(
resultantDescriptor: SerialDescriptor,
crossinline deserialize: T.(T) -> R,
crossinline serialize: R.(R) -> T,
): KSerializer {
return object : KSerializer {
override val descriptor: SerialDescriptor get() = resultantDescriptor
override fun deserialize(decoder: Decoder): R = [email protected](decoder).let { deserialize(it, it) }
override fun serialize(encoder: Encoder, value: R) = serialize(encoder, value.let { serialize(it, it) })
}
}
@OptIn(ExperimentalSerializationApi::class)
public inline fun KSerializer.mapPrimitive(
serialName: String,
crossinline deserialize: (T) -> R,
crossinline serialize: R.(R) -> T,
): KSerializer {
val kind = [email protected]
check(kind is PrimitiveKind) { "kind must be PrimitiveKind but found $kind" }
return object : KSerializer {
override fun deserialize(decoder: Decoder): R =
[email protected](decoder).let(deserialize)
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(serialName, kind)
override fun serialize(encoder: Encoder, value: R) =
[email protected](encoder, value.let { serialize(it, it) })
}
}
public fun MiraiFile.loadNotBlankAs(
serializer: DeserializationStrategy,
stringFormat: StringFormat,
): T? {
if (!this.exists() || this.length == 0L) {
return null
}
return stringFormat.decodeFromString(serializer, this.readText())
}
public fun MiraiFile.loadNotBlankAs(
serializer: DeserializationStrategy,
binaryFormat: BinaryFormat,
): T? {
if (!this.exists() || this.length == 0L) {
return null
}
return binaryFormat.decodeFromByteArray(serializer, this.readBytes())
}