Skip to content

Commit

Permalink
JAVA-5342 Fix encoding generics with nullable type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
cliffred committed Feb 28, 2024
1 parent 2260ab5 commit 5b1db72
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ internal class DefaultBsonEncoder(
return true
}

override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) {
deferredElementName?.let {
if (value != null || configuration.explicitNulls) {
encodeName(it)
super.encodeSerializableValue(serializer, value)
} else {
deferredElementName = null
}
}
?: super.encodeSerializableValue(serializer, value)
}

override fun <T : Any> encodeNullableSerializableValue(serializer: SerializationStrategy<T>, value: T?) {
deferredElementName?.let {
if (value != null || configuration.explicitNulls) {
Expand All @@ -158,7 +170,14 @@ internal class DefaultBsonEncoder(
override fun encodeDouble(value: Double) = writer.writeDouble(value)
override fun encodeInt(value: Int) = writer.writeInt32(value)
override fun encodeLong(value: Long) = writer.writeInt64(value)
override fun encodeNull() = writer.writeNull()
override fun encodeNull() {
deferredElementName?.let {
if (configuration.explicitNulls) {
encodeName(it)
}
}
writer.writeNull()
}

override fun encodeString(value: String) {
when (state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import org.bson.BsonUndefined
import org.bson.codecs.DecoderContext
import org.bson.codecs.EncoderContext
import org.bson.codecs.configuration.CodecConfigurationException
import org.bson.codecs.kotlinx.samples.Box
import org.bson.codecs.kotlinx.samples.DataClassBsonValues
import org.bson.codecs.kotlinx.samples.DataClassContainsOpen
import org.bson.codecs.kotlinx.samples.DataClassContainsValueClass
Expand Down Expand Up @@ -76,6 +77,7 @@ import org.bson.codecs.kotlinx.samples.DataClassWithMutableMap
import org.bson.codecs.kotlinx.samples.DataClassWithMutableSet
import org.bson.codecs.kotlinx.samples.DataClassWithNestedParameterized
import org.bson.codecs.kotlinx.samples.DataClassWithNestedParameterizedDataClass
import org.bson.codecs.kotlinx.samples.DataClassWithNullableGeneric
import org.bson.codecs.kotlinx.samples.DataClassWithNulls
import org.bson.codecs.kotlinx.samples.DataClassWithPair
import org.bson.codecs.kotlinx.samples.DataClassWithParameterizedDataClass
Expand Down Expand Up @@ -199,6 +201,27 @@ class KotlinSerializerCodecTest {
assertRoundTrips(expectedNulls, dataClass, altConfiguration)
}

@Test
fun testDataClassWithNullableGenericsNotNull() {
val expected =
"""{
| "box": {"boxed": "String"}
|}"""
.trimMargin()

val dataClass = DataClassWithNullableGeneric(Box("String"))
assertRoundTrips(expected, dataClass)
}

@Test
fun testDataClassWithNullableGenericsNull() {
val expectedDefault = """{"box": {}}"""
val dataClass = DataClassWithNullableGeneric(Box(null))
assertRoundTrips(expectedDefault, dataClass)
val expectedNull = """{"box": {"boxed": null}}"""
assertRoundTrips(expectedNull, dataClass, altConfiguration)
}

@Test
fun testDataClassSelfReferential() {
val expected =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,7 @@ data class DataClassWithFailingInit(val id: String) {
}

@Serializable data class DataClassWithSequence(val value: Sequence<String>)

@Serializable data class Box<T>(val boxed: T)

@Serializable data class DataClassWithNullableGeneric(val box: Box<String?>)

0 comments on commit 5b1db72

Please sign in to comment.