1 /* 2 * Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 @file:OptIn(ExperimentalSerializationApi::class) 5 package kotlinx.serialization.internal 6 7 import kotlinx.serialization.* 8 import kotlinx.serialization.descriptors.* 9 import kotlinx.serialization.encoding.* 10 11 /** 12 * Use [KSerializer.nullable][nullable] instead. 13 * @suppress internal API 14 */ 15 @PublishedApi 16 @OptIn(ExperimentalSerializationApi::class) 17 internal class NullableSerializer<T : Any>(private val serializer: KSerializer<T>) : KSerializer<T?> { 18 override val descriptor: SerialDescriptor = SerialDescriptorForNullable(serializer.descriptor) 19 serializenull20 override fun serialize(encoder: Encoder, value: T?) { 21 if (value != null) { 22 encoder.encodeNotNullMark() 23 encoder.encodeSerializableValue(serializer, value) 24 } else { 25 encoder.encodeNull() 26 } 27 } 28 deserializenull29 override fun deserialize(decoder: Decoder): T? { 30 return if (decoder.decodeNotNullMark()) decoder.decodeSerializableValue(serializer) else decoder.decodeNull() 31 } 32 equalsnull33 override fun equals(other: Any?): Boolean { 34 if (this === other) return true 35 if (other == null || this::class != other::class) return false 36 other as NullableSerializer<*> 37 if (serializer != other.serializer) return false 38 return true 39 } 40 hashCodenull41 override fun hashCode(): Int { 42 return serializer.hashCode() 43 } 44 } 45 46 @OptIn(ExperimentalSerializationApi::class) 47 internal class SerialDescriptorForNullable( 48 internal val original: SerialDescriptor 49 ) : SerialDescriptor by original, CachedNames { 50 51 override val serialName: String = original.serialName + "?" 52 override val serialNames: Set<String> = original.cachedSerialNames() 53 override val isNullable: Boolean 54 get() = true 55 equalsnull56 override fun equals(other: Any?): Boolean { 57 if (this === other) return true 58 if (other !is SerialDescriptorForNullable) return false 59 if (original != other.original) return false 60 return true 61 } 62 toStringnull63 override fun toString(): String { 64 return "$original?" 65 } 66 hashCodenull67 override fun hashCode(): Int { 68 return original.hashCode() * 31 69 } 70 } 71