summaryrefslogtreecommitdiff
path: root/core/commonMain/src/kotlinx/serialization/internal/Tuples.kt
diff options
context:
space:
mode:
authorVsevolod Tolstopyatov <qwwdfsad@gmail.com>2020-09-14 04:04:34 -0700
committerGitHub <noreply@github.com>2020-09-14 14:04:34 +0300
commit0e4e0e729f97df1844a266647c2c4786ed780b2f (patch)
treeacc8e0a73c01bf223c5b92b4200e963355e0558d /core/commonMain/src/kotlinx/serialization/internal/Tuples.kt
parent1df4d619058cd8774cf3b895bde660d15483d935 (diff)
downloadkotlinx.serialization-0e4e0e729f97df1844a266647c2c4786ed780b2f.tar.gz
Extract JSON to a separate dependency, rename 'runtime' to 'core' (#1062)
* Introduce JsonInternalDependencies * Make SealedClassSerializer public * Duplicate test code in a few places Fixes #994
Diffstat (limited to 'core/commonMain/src/kotlinx/serialization/internal/Tuples.kt')
-rw-r--r--core/commonMain/src/kotlinx/serialization/internal/Tuples.kt191
1 files changed, 191 insertions, 0 deletions
diff --git a/core/commonMain/src/kotlinx/serialization/internal/Tuples.kt b/core/commonMain/src/kotlinx/serialization/internal/Tuples.kt
new file mode 100644
index 00000000..8bd4deb2
--- /dev/null
+++ b/core/commonMain/src/kotlinx/serialization/internal/Tuples.kt
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2017-2020 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.*
+
+@SharedImmutable
+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"
+
+@InternalSerializationApi
+@Deprecated(message = deprecationMessage, level = DeprecationLevel.HIDDEN)
+public sealed class KeyValueSerializer<K, V, R>(
+ protected val keySerializer: KSerializer<K>,
+ protected val valueSerializer: KSerializer<V>
+) : KSerializer<R> {
+
+ 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 {
+ val composite = decoder.beginStructure(descriptor)
+ if (composite.decodeSequentially()) {
+ val key = composite.decodeSerializableElement(descriptor, 0, keySerializer)
+ val value = composite.decodeSerializableElement(descriptor, 1, valueSerializer)
+ return toResult(key, value)
+ }
+
+ var key: Any? = NULL
+ var value: Any? = NULL
+ mainLoop@ while (true) {
+ when (val idx = composite.decodeElementIndex(descriptor)) {
+ CompositeDecoder.DECODE_DONE -> {
+ break@mainLoop
+ }
+ 0 -> {
+ key = composite.decodeSerializableElement(descriptor, 0, keySerializer)
+ }
+ 1 -> {
+ value = composite.decodeSerializableElement(descriptor, 1, valueSerializer)
+ }
+ else -> throw SerializationException("Invalid index: $idx")
+ }
+ }
+ composite.endStructure(descriptor)
+ if (key === NULL) throw SerializationException("Element 'key' is missing")
+ if (value === NULL) throw SerializationException("Element 'value' is missing")
+ @Suppress("UNCHECKED_CAST")
+ return toResult(key as K, value as V)
+ }
+}
+
+@InternalSerializationApi
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
+@Deprecated(
+ message = deprecationMessage, level = DeprecationLevel.HIDDEN, replaceWith = ReplaceWith(
+ "MapEntrySerializer(keySerializer, valueSerializer, cSerializer)",
+ imports = ["kotlinx.serialization.builtins.MapEntrySerializer"]
+ )
+)
+public class MapEntrySerializer<K, V>(
+ keySerializer: KSerializer<K>,
+ valueSerializer: KSerializer<V>
+) : KeyValueSerializer<K, V, Map.Entry<K, V>>(keySerializer, valueSerializer) {
+ private data class MapEntry<K, V>(override val key: K, override val value: V) : Map.Entry<K, V>
+
+ /*
+ * 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<K, V>.key: K get() = this.key
+ override val Map.Entry<K, V>.value: V get() = this.value
+ override fun toResult(key: K, value: V): Map.Entry<K, V> = MapEntry(key, value)
+}
+
+@InternalSerializationApi
+@Deprecated(
+ message = deprecationMessage, level = DeprecationLevel.HIDDEN, replaceWith = ReplaceWith(
+ "PairSerializer(keySerializer, valueSerializer, cSerializer)",
+ imports = ["kotlinx.serialization.builtins.PairSerializer"]
+ )
+)
+public class PairSerializer<K, V>(
+ keySerializer: KSerializer<K>,
+ valueSerializer: KSerializer<V>
+) : KeyValueSerializer<K, V, Pair<K, V>>(keySerializer, valueSerializer) {
+ override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.Pair") {
+ element("first", keySerializer.descriptor)
+ element("second", valueSerializer.descriptor)
+ }
+ override val Pair<K, V>.key: K get() = this.first
+ override val Pair<K, V>.value: V get() = this.second
+
+ override fun toResult(key: K, value: V): Pair<K, V> = key to value
+}
+
+
+@InternalSerializationApi
+@Deprecated(
+ message = deprecationMessage,
+ level = DeprecationLevel.HIDDEN,
+ replaceWith = ReplaceWith(
+ "TripleSerializer(aSerializer, bSerializer, cSerializer)",
+ imports = ["kotlinx.serialization.builtins.TripleSerializer"]
+ )
+)
+public class TripleSerializer<A, B, C>(
+ private val aSerializer: KSerializer<A>,
+ private val bSerializer: KSerializer<B>,
+ private val cSerializer: KSerializer<C>
+) : KSerializer<Triple<A, B, C>> {
+
+ 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<A, B, C>) {
+ 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<A, B, C> {
+ val composite = decoder.beginStructure(descriptor)
+ if (composite.decodeSequentially()) {
+ return decodeSequentially(composite)
+ }
+ return decodeStructure(composite)
+ }
+
+ private fun decodeSequentially(composite: CompositeDecoder): Triple<A, B, C> {
+ 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<A, B, C> {
+ 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)
+ }
+}