Skip to content

Commit

Permalink
Correctly implement TaggedDecoder's decodeNullableSerializableElement
Browse files Browse the repository at this point in the history
  • Loading branch information
pschichtel committed Oct 7, 2023
1 parent 9ac4c5f commit 5d79745
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
decodeSerializableElement(descriptor, index, deserializer, previousValue)
}
}
11 changes: 8 additions & 3 deletions core/commonMain/src/kotlinx/serialization/encoding/Decoding.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down
11 changes: 4 additions & 7 deletions core/commonMain/src/kotlinx/serialization/internal/Tagged.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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() || deserializer.descriptor.isNullable) decodeSerializableValue(
deserializer,
previousValue
) else decodeNull()
): T? = tagBlock(descriptor.getTag(index)) {
decodeIfNullable(deserializer) {
decodeSerializableElement(descriptor, index, deserializer, previousValue)
}
}

private fun <E> tagBlock(tag: Tag, block: () -> E): E {
pushTag(tag)
Expand Down

0 comments on commit 5d79745

Please sign in to comment.