Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify customization of bson-kotlinx #1293

Merged
merged 2 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.bson.codecs.kotlinx

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.modules.SerializersModule
import org.bson.codecs.Codec
import org.bson.codecs.configuration.CodecProvider
import org.bson.codecs.configuration.CodecRegistry
Expand All @@ -24,8 +26,12 @@ import org.bson.codecs.configuration.CodecRegistry
*
* The underlying class must be annotated with the `@Serializable`.
*/
public class KotlinSerializerCodecProvider : CodecProvider {
@OptIn(ExperimentalSerializationApi::class)
public class KotlinSerializerCodecProvider(
private val serializersModule: SerializersModule = defaultSerializersModule,
private val bsonConfiguration: BsonConfiguration = BsonConfiguration()
) : CodecProvider {

override fun <T : Any> get(clazz: Class<T>, registry: CodecRegistry): Codec<T>? =
KotlinSerializerCodec.create(clazz.kotlin)
KotlinSerializerCodec.create(clazz.kotlin, serializersModule, bsonConfiguration)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.plus
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
import org.bson.BsonDocument
import org.bson.BsonDocumentWriter
import org.bson.codecs.EncoderContext
import org.bson.codecs.kotlinx.samples.DataClassContainsOpen
import org.bson.codecs.kotlinx.samples.DataClassOpen
import org.bson.codecs.kotlinx.samples.DataClassOpenA
import org.bson.codecs.kotlinx.samples.DataClassOpenB
import org.bson.codecs.kotlinx.samples.DataClassParameterized
import org.bson.codecs.kotlinx.samples.DataClassWithSimpleValues
import org.bson.conversions.Bson
Expand Down Expand Up @@ -60,4 +72,34 @@ class KotlinSerializerCodecProviderTest {
assertTrue { codec is KotlinSerializerCodec }
assertEquals(DataClassWithSimpleValues::class.java, codec.encoderClass)
}

@OptIn(ExperimentalSerializationApi::class)
@Test
fun shouldAllowOverridingOfSerializersModuleAndBsonConfigurationInConstructor() {

val serializersModule =
SerializersModule {
this.polymorphic(DataClassOpen::class) {
this.subclass(DataClassOpenA::class)
this.subclass(DataClassOpenB::class)
}
} + defaultSerializersModule

val bsonConfiguration = BsonConfiguration(classDiscriminator = "__type")
val dataClassContainsOpenB = DataClassContainsOpen(DataClassOpenB(1))

val codec =
KotlinSerializerCodecProvider(serializersModule, bsonConfiguration)
.get(DataClassContainsOpen::class.java, Bson.DEFAULT_CODEC_REGISTRY)!!

assertTrue { codec is KotlinSerializerCodec }
val encodedDocument = BsonDocument()
val writer = BsonDocumentWriter(encodedDocument)
codec.encode(writer, dataClassContainsOpenB, EncoderContext.builder().build())
writer.flush()

assertEquals(
BsonDocument.parse("""{"open": {"__type": "org.bson.codecs.kotlinx.samples.DataClassOpenB", "b": 1}}"""),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[optional]
We may also test that decoding this BSON succeeds and produces an object equal to dataClassContainsOpenB. This way we'll know that the custom classDiscriminator is used not only by the encoder, but also by the decoder.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

encodedDocument)
}
}