summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorPhillip Schichtel <pschichtel@users.noreply.github.com>2023-10-27 14:54:55 +0200
committerGitHub <noreply@github.com>2023-10-27 14:54:55 +0200
commitcf71e0881b284ce8b2d3cf67218869fec4e37d82 (patch)
treeba38a5c9d694d8436e8ad92dc48826156f808dfa /core
parentb44f03f618f43a2ea691943077538bef5fe8ffd4 (diff)
downloadkotlinx.serialization-cf71e0881b284ce8b2d3cf67218869fec4e37d82.tar.gz
Fix TaggedDecoder nullable decoding (#2456)
Make the TaggedDecoder.decodeNullableSerializableElement implementation consistent with AbstractDecoder, so it is possible to differentiate nullable and non-nullable serializers. Fixes #2455
Diffstat (limited to 'core')
-rw-r--r--core/commonMain/src/kotlinx/serialization/encoding/AbstractDecoder.kt5
-rw-r--r--core/commonMain/src/kotlinx/serialization/encoding/Decoding.kt11
-rw-r--r--core/commonMain/src/kotlinx/serialization/internal/Tagged.kt11
3 files changed, 14 insertions, 13 deletions
diff --git a/core/commonMain/src/kotlinx/serialization/encoding/AbstractDecoder.kt b/core/commonMain/src/kotlinx/serialization/encoding/AbstractDecoder.kt
index fad7ef87..ffe6dd37 100644
--- a/core/commonMain/src/kotlinx/serialization/encoding/AbstractDecoder.kt
+++ b/core/commonMain/src/kotlinx/serialization/encoding/AbstractDecoder.kt
@@ -74,8 +74,7 @@ public abstract class AbstractDecoder : Decoder, CompositeDecoder {
index: Int,
deserializer: DeserializationStrategy<T?>,
previousValue: T?
- ): T? {
- val isNullabilitySupported = deserializer.descriptor.isNullable
- return if (isNullabilitySupported || decodeNotNullMark()) decodeSerializableValue(deserializer, previousValue) else decodeNull()
+ ): T? = decodeIfNullable(deserializer) {
+ decodeSerializableValue(deserializer, previousValue)
}
}
diff --git a/core/commonMain/src/kotlinx/serialization/encoding/Decoding.kt b/core/commonMain/src/kotlinx/serialization/encoding/Decoding.kt
index f29c8057..dc4aa2ab 100644
--- a/core/commonMain/src/kotlinx/serialization/encoding/Decoding.kt
+++ b/core/commonMain/src/kotlinx/serialization/encoding/Decoding.kt
@@ -260,12 +260,17 @@ public interface Decoder {
* Decodes the nullable value of type [T] by delegating the decoding process to the given [deserializer].
*/
@ExperimentalSerializationApi
- public fun <T : Any> decodeNullableSerializableValue(deserializer: DeserializationStrategy<T?>): T? {
- val isNullabilitySupported = deserializer.descriptor.isNullable
- return if (isNullabilitySupported || decodeNotNullMark()) decodeSerializableValue(deserializer) else decodeNull()
+ public fun <T : Any> decodeNullableSerializableValue(deserializer: DeserializationStrategy<T?>): T? = decodeIfNullable(deserializer) {
+ decodeSerializableValue(deserializer)
}
}
+@OptIn(ExperimentalSerializationApi::class)
+internal inline fun <T : Any> Decoder.decodeIfNullable(deserializer: DeserializationStrategy<T?>, block: () -> T?): T? {
+ val isNullabilitySupported = deserializer.descriptor.isNullable
+ return if (isNullabilitySupported || decodeNotNullMark()) block() else decodeNull()
+}
+
/**
* [CompositeDecoder] is a part of decoding process that is bound to a particular structured part of
* the serialized form, described by the serial descriptor passed to [Decoder.beginStructure].
diff --git a/core/commonMain/src/kotlinx/serialization/internal/Tagged.kt b/core/commonMain/src/kotlinx/serialization/internal/Tagged.kt
index 3af5d351..cf71388c 100644
--- a/core/commonMain/src/kotlinx/serialization/internal/Tagged.kt
+++ b/core/commonMain/src/kotlinx/serialization/internal/Tagged.kt
@@ -206,7 +206,6 @@ public abstract class TaggedDecoder<Tag : Any?> : Decoder, CompositeDecoder {
protected open fun <T : Any?> decodeSerializableValue(deserializer: DeserializationStrategy<T>, previousValue: T?): T =
decodeSerializableValue(deserializer)
-
// ---- Implementation of low-level API ----
override fun decodeInline(descriptor: SerialDescriptor): Decoder =
@@ -284,13 +283,11 @@ public abstract class TaggedDecoder<Tag : Any?> : Decoder, CompositeDecoder {
index: Int,
deserializer: DeserializationStrategy<T?>,
previousValue: T?
- ): T? =
- tagBlock(descriptor.getTag(index)) {
- if (decodeNotNullMark()) decodeSerializableValue(
- deserializer,
- previousValue
- ) else decodeNull()
+ ): T? = tagBlock(descriptor.getTag(index)) {
+ decodeIfNullable(deserializer) {
+ decodeSerializableValue(deserializer, previousValue)
}
+ }
private fun <E> tagBlock(tag: Tag, block: () -> E): E {
pushTag(tag)