Skip to content

Commit ae360c9

Browse files
committed
Fix encoding nullable generics
1 parent 2260ab5 commit ae360c9

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonEncoder.kt

+20-1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ internal class DefaultBsonEncoder(
139139
return true
140140
}
141141

142+
override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) {
143+
deferredElementName?.let {
144+
if (value != null || configuration.explicitNulls) {
145+
encodeName(it)
146+
super.encodeSerializableValue(serializer, value)
147+
} else {
148+
deferredElementName = null
149+
}
150+
}
151+
?: super.encodeSerializableValue(serializer, value)
152+
}
153+
142154
override fun <T : Any> encodeNullableSerializableValue(serializer: SerializationStrategy<T>, value: T?) {
143155
deferredElementName?.let {
144156
if (value != null || configuration.explicitNulls) {
@@ -158,7 +170,14 @@ internal class DefaultBsonEncoder(
158170
override fun encodeDouble(value: Double) = writer.writeDouble(value)
159171
override fun encodeInt(value: Int) = writer.writeInt32(value)
160172
override fun encodeLong(value: Long) = writer.writeInt64(value)
161-
override fun encodeNull() = writer.writeNull()
173+
override fun encodeNull() {
174+
deferredElementName?.let {
175+
if (configuration.explicitNulls) {
176+
encodeName(it)
177+
}
178+
}
179+
writer.writeNull()
180+
}
162181

163182
override fun encodeString(value: String) {
164183
when (state) {

bson-kotlinx/src/test/kotlin/org/bson/codecs/kotlinx/KotlinSerializerCodecTest.kt

+23
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.bson.BsonUndefined
3333
import org.bson.codecs.DecoderContext
3434
import org.bson.codecs.EncoderContext
3535
import org.bson.codecs.configuration.CodecConfigurationException
36+
import org.bson.codecs.kotlinx.samples.Box
3637
import org.bson.codecs.kotlinx.samples.DataClassBsonValues
3738
import org.bson.codecs.kotlinx.samples.DataClassContainsOpen
3839
import org.bson.codecs.kotlinx.samples.DataClassContainsValueClass
@@ -76,6 +77,7 @@ import org.bson.codecs.kotlinx.samples.DataClassWithMutableMap
7677
import org.bson.codecs.kotlinx.samples.DataClassWithMutableSet
7778
import org.bson.codecs.kotlinx.samples.DataClassWithNestedParameterized
7879
import org.bson.codecs.kotlinx.samples.DataClassWithNestedParameterizedDataClass
80+
import org.bson.codecs.kotlinx.samples.DataClassWithNullableGeneric
7981
import org.bson.codecs.kotlinx.samples.DataClassWithNulls
8082
import org.bson.codecs.kotlinx.samples.DataClassWithPair
8183
import org.bson.codecs.kotlinx.samples.DataClassWithParameterizedDataClass
@@ -199,6 +201,27 @@ class KotlinSerializerCodecTest {
199201
assertRoundTrips(expectedNulls, dataClass, altConfiguration)
200202
}
201203

204+
@Test
205+
fun testDataClassWithNullableGenericsNotNull() {
206+
val expected =
207+
"""{
208+
| "box": {"boxed": "String"}
209+
|}"""
210+
.trimMargin()
211+
212+
val dataClass = DataClassWithNullableGeneric(Box("String"))
213+
assertRoundTrips(expected, dataClass)
214+
}
215+
216+
@Test
217+
fun testDataClassWithNullableGenericsNull() {
218+
val expectedDefault = """{"box": {}}"""
219+
val dataClass = DataClassWithNullableGeneric(Box(null))
220+
assertRoundTrips(expectedDefault, dataClass)
221+
val expectedNull = """{"box": {"boxed": null}}"""
222+
assertRoundTrips(expectedNull, dataClass, altConfiguration)
223+
}
224+
202225
@Test
203226
fun testDataClassSelfReferential() {
204227
val expected =

bson-kotlinx/src/test/kotlin/org/bson/codecs/kotlinx/samples/DataClasses.kt

+4
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,7 @@ data class DataClassWithFailingInit(val id: String) {
285285
}
286286

287287
@Serializable data class DataClassWithSequence(val value: Sequence<String>)
288+
289+
@Serializable data class Box<T>(val boxed: T)
290+
291+
@Serializable data class DataClassWithNullableGeneric(val box: Box<String?>)

0 commit comments

Comments
 (0)