commonMain.io.ktor.serialization.kotlinx.SerializerLookup.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ktor-serialization-kotlinx-androidnativex86 Show documentation
Show all versions of ktor-serialization-kotlinx-androidnativex86 Show documentation
Ktor is a framework for quickly creating web applications in Kotlin with minimal effort.
The newest version!
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
package io.ktor.serialization.kotlinx
import io.ktor.util.reflect.*
import io.ktor.utils.io.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.*
import kotlinx.serialization.modules.*
@InternalSerializationApi
@ExperimentalSerializationApi
/**
* Attempts to create a serializer for the given [typeInfo]
*/
public fun SerializersModule.serializerForTypeInfo(typeInfo: TypeInfo): KSerializer<*> {
val module = this
return typeInfo.kotlinType
?.let { type ->
if (type.arguments.isEmpty()) {
null // fallback to a simple case because of
// https://github.com/Kotlin/kotlinx.serialization/issues/1870
} else {
module.serializerOrNull(type)
}
}
?: module.getContextual(typeInfo.type)?.maybeNullable(typeInfo)
?: typeInfo.type.serializer().maybeNullable(typeInfo)
}
private fun KSerializer.maybeNullable(typeInfo: TypeInfo): KSerializer<*> {
return if (typeInfo.kotlinType?.isMarkedNullable == true) this.nullable else this
}
@Suppress("UNCHECKED_CAST")
@InternalAPI
public fun guessSerializer(value: Any?, module: SerializersModule): KSerializer = when (value) {
null -> String.serializer().nullable
is List<*> -> ListSerializer(value.elementSerializer(module))
is Array<*> -> value.firstOrNull()?.let { guessSerializer(it, module) } ?: ListSerializer(String.serializer())
is Set<*> -> SetSerializer(value.elementSerializer(module))
is Map<*, *> -> {
val keySerializer = value.keys.elementSerializer(module)
val valueSerializer = value.values.elementSerializer(module)
MapSerializer(keySerializer, valueSerializer)
}
else -> {
@OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
module.getContextual(value::class) ?: value::class.serializer()
}
} as KSerializer
@OptIn(ExperimentalSerializationApi::class, InternalAPI::class)
private fun Collection<*>.elementSerializer(module: SerializersModule): KSerializer<*> {
val serializers: List> =
filterNotNull().map { guessSerializer(it, module) }.distinctBy { it.descriptor.serialName }
if (serializers.size > 1) {
error(
"Serializing collections of different element types is not yet supported. " +
"Selected serializers: ${serializers.map { it.descriptor.serialName }}",
)
}
val selected = serializers.singleOrNull() ?: String.serializer()
if (selected.descriptor.isNullable) {
return selected
}
@Suppress("UNCHECKED_CAST")
selected as KSerializer
if (any { it == null }) {
return selected.nullable
}
return selected
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy