59 lines
2.6 KiB
Kotlin
59 lines
2.6 KiB
Kotlin
package dev.inmo.postssystem.services.posts.common
|
|
|
|
import dev.inmo.micro_utils.common.FileName
|
|
import dev.inmo.micro_utils.mime_types.MimeType
|
|
import dev.inmo.micro_utils.mime_types.MimeTypeSerializer
|
|
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
|
|
import dev.inmo.postssystem.features.content.common.BinaryContent
|
|
import kotlinx.serialization.*
|
|
import kotlinx.serialization.descriptors.*
|
|
import kotlinx.serialization.encoding.*
|
|
import kotlin.reflect.KClass
|
|
|
|
@Serializer(BinaryContent::class)
|
|
class BinaryContentSerializer<T: SimpleInputProvider>(
|
|
private val kClass: KClass<T>,
|
|
private val serializer: KSerializer<T>
|
|
) : KSerializer<BinaryContent> {
|
|
@OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
|
|
override val descriptor: SerialDescriptor = buildSerialDescriptor(
|
|
"BinaryContent",
|
|
SerialKind.CONTEXTUAL
|
|
) {
|
|
element("filename", FileName.serializer().descriptor)
|
|
element("mimetype", MimeTypeSerializer.descriptor)
|
|
element("data", serializer.descriptor)
|
|
}
|
|
|
|
override fun deserialize(decoder: Decoder): BinaryContent {
|
|
return decoder.decodeStructure(descriptor) {
|
|
var fileName: FileName? = null
|
|
var mimeType: MimeType? = null
|
|
var data: T? = null
|
|
while (true) {
|
|
when (val index = decodeElementIndex(descriptor)) {
|
|
0 -> fileName = decodeSerializableElement(descriptor, 0, FileName.serializer())
|
|
1 -> mimeType = decodeSerializableElement(descriptor, 1, MimeTypeSerializer)
|
|
2 -> data = decodeSerializableElement(descriptor, 2, serializer)
|
|
CompositeDecoder.DECODE_DONE -> break
|
|
else -> error("Unexpected index: $index")
|
|
}
|
|
}
|
|
BinaryContent(
|
|
fileName ?: error("Filename must be presented, but was absent"),
|
|
mimeType ?: error("Mimetype must be presented, but was absent"),
|
|
data ?: error("Data must be presented, but was absent")
|
|
)
|
|
}
|
|
}
|
|
|
|
override fun serialize(encoder: Encoder, value: BinaryContent) {
|
|
require(kClass.isInstance(value.inputProvider)) { "${value.inputProvider} do not inherit $kClass" }
|
|
encoder.encodeStructure(descriptor) {
|
|
encodeSerializableElement(descriptor, 0, FileName.serializer(), value.filename)
|
|
encodeSerializableElement(descriptor, 1, MimeTypeSerializer, value.mimeType)
|
|
encodeSerializableElement(descriptor, 2, serializer, value.inputProvider as T)
|
|
}
|
|
}
|
|
}
|