commonMain.kotlinx.serialization.internal.Tuples.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlinx-serialization-core-jvm Show documentation
Show all versions of kotlinx-serialization-core-jvm Show documentation
Kotlin multiplatform serialization runtime library
/*
* Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
@file:Suppress("DEPRECATION_ERROR")
@file:OptIn(ExperimentalSerializationApi::class)
package kotlinx.serialization.internal
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlin.native.concurrent.*
private val NULL = Any()
private const val deprecationMessage =
"This class is used only by the plugin in generated code and should not be used directly. Use corresponding factory functions instead"
@PublishedApi
internal sealed class KeyValueSerializer(
protected val keySerializer: KSerializer,
protected val valueSerializer: KSerializer
) : KSerializer {
protected abstract val R.key: K
protected abstract val R.value: V
protected abstract fun toResult(key: K, value: V): R
override fun serialize(encoder: Encoder, value: R) {
val structuredEncoder = encoder.beginStructure(descriptor)
structuredEncoder.encodeSerializableElement(descriptor, 0, keySerializer, value.key)
structuredEncoder.encodeSerializableElement(descriptor, 1, valueSerializer, value.value)
structuredEncoder.endStructure(descriptor)
}
override fun deserialize(decoder: Decoder): R = decoder.decodeStructure(descriptor) {
if (decodeSequentially()) {
val key = decodeSerializableElement(descriptor, 0, keySerializer)
val value = decodeSerializableElement(descriptor, 1, valueSerializer)
return@decodeStructure toResult(key, value)
}
var key: Any? = NULL
var value: Any? = NULL
mainLoop@ while (true) {
when (val idx = decodeElementIndex(descriptor)) {
CompositeDecoder.DECODE_DONE -> {
break@mainLoop
}
0 -> {
key = decodeSerializableElement(descriptor, 0, keySerializer)
}
1 -> {
value = decodeSerializableElement(descriptor, 1, valueSerializer)
}
else -> throw SerializationException("Invalid index: $idx")
}
}
if (key === NULL) throw SerializationException("Element 'key' is missing")
if (value === NULL) throw SerializationException("Element 'value' is missing")
@Suppress("UNCHECKED_CAST")
return@decodeStructure toResult(key as K, value as V)
}
}
@PublishedApi
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
internal class MapEntrySerializer(
keySerializer: KSerializer,
valueSerializer: KSerializer
) : KeyValueSerializer>(keySerializer, valueSerializer) {
private data class MapEntry(override val key: K, override val value: V) : Map.Entry
/*
* Kind 'MAP' because it is represented in a map-like manner with "key: value" serialized directly
*/
override val descriptor: SerialDescriptor = buildSerialDescriptor("kotlin.collections.Map.Entry", StructureKind.MAP) {
element("key", keySerializer.descriptor)
element("value", valueSerializer.descriptor)
}
override val Map.Entry.key: K get() = this.key
override val Map.Entry.value: V get() = this.value
override fun toResult(key: K, value: V): Map.Entry = MapEntry(key, value)
}
@PublishedApi
internal class PairSerializer(
keySerializer: KSerializer,
valueSerializer: KSerializer
) : KeyValueSerializer>(keySerializer, valueSerializer) {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.Pair") {
element("first", keySerializer.descriptor)
element("second", valueSerializer.descriptor)
}
override val Pair.key: K get() = this.first
override val Pair.value: V get() = this.second
override fun toResult(key: K, value: V): Pair = key to value
}
@PublishedApi
internal class TripleSerializer(
private val aSerializer: KSerializer,
private val bSerializer: KSerializer,
private val cSerializer: KSerializer
) : KSerializer> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.Triple") {
element("first", aSerializer.descriptor)
element("second", bSerializer.descriptor)
element("third", cSerializer.descriptor)
}
override fun serialize(encoder: Encoder, value: Triple) {
val structuredEncoder = encoder.beginStructure(descriptor)
structuredEncoder.encodeSerializableElement(descriptor, 0, aSerializer, value.first)
structuredEncoder.encodeSerializableElement(descriptor, 1, bSerializer, value.second)
structuredEncoder.encodeSerializableElement(descriptor, 2, cSerializer, value.third)
structuredEncoder.endStructure(descriptor)
}
override fun deserialize(decoder: Decoder): Triple {
val composite = decoder.beginStructure(descriptor)
if (composite.decodeSequentially()) {
return decodeSequentially(composite)
}
return decodeStructure(composite)
}
private fun decodeSequentially(composite: CompositeDecoder): Triple {
val a = composite.decodeSerializableElement(descriptor, 0, aSerializer)
val b = composite.decodeSerializableElement(descriptor, 1, bSerializer)
val c = composite.decodeSerializableElement(descriptor, 2, cSerializer)
composite.endStructure(descriptor)
return Triple(a, b, c)
}
private fun decodeStructure(composite: CompositeDecoder): Triple {
var a: Any? = NULL
var b: Any? = NULL
var c: Any? = NULL
mainLoop@ while (true) {
when (val index = composite.decodeElementIndex(descriptor)) {
CompositeDecoder.DECODE_DONE -> {
break@mainLoop
}
0 -> {
a = composite.decodeSerializableElement(descriptor, 0, aSerializer)
}
1 -> {
b = composite.decodeSerializableElement(descriptor, 1, bSerializer)
}
2 -> {
c = composite.decodeSerializableElement(descriptor, 2, cSerializer)
}
else -> throw SerializationException("Unexpected index $index")
}
}
composite.endStructure(descriptor)
if (a === NULL) throw SerializationException("Element 'first' is missing")
if (b === NULL) throw SerializationException("Element 'second' is missing")
if (c === NULL) throw SerializationException("Element 'third' is missing")
@Suppress("UNCHECKED_CAST")
return Triple(a as A, b as B, c as C)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy