Skip to content

Commit 467c509

Browse files
Add implementation for JsonEncoder in DefaultBsonEncoder
Signed-off-by: Mark <mark.vogel@nomadgcs.com>
1 parent c065a6b commit 467c509

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

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

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,24 @@ import kotlinx.serialization.descriptors.SerialKind
2525
import kotlinx.serialization.descriptors.StructureKind
2626
import kotlinx.serialization.encoding.AbstractEncoder
2727
import kotlinx.serialization.encoding.CompositeEncoder
28+
import kotlinx.serialization.json.Json
29+
import kotlinx.serialization.json.JsonArray
30+
import kotlinx.serialization.json.JsonElement
31+
import kotlinx.serialization.json.JsonEncoder
32+
import kotlinx.serialization.json.JsonNull
33+
import kotlinx.serialization.json.JsonObject
34+
import kotlinx.serialization.json.JsonPrimitive
35+
import kotlinx.serialization.json.double
36+
import kotlinx.serialization.json.int
37+
import kotlinx.serialization.json.long
2838
import kotlinx.serialization.modules.SerializersModule
2939
import org.bson.BsonValue
3040
import org.bson.BsonWriter
3141
import org.bson.codecs.BsonValueCodec
3242
import org.bson.codecs.EncoderContext
43+
import org.bson.types.Decimal128
3344
import org.bson.types.ObjectId
45+
import java.math.BigDecimal
3446

3547
/**
3648
* The BsonEncoder interface
@@ -62,17 +74,29 @@ internal class DefaultBsonEncoder(
6274
private val writer: BsonWriter,
6375
override val serializersModule: SerializersModule,
6476
private val configuration: BsonConfiguration
65-
) : BsonEncoder, AbstractEncoder() {
77+
) : BsonEncoder, JsonEncoder, AbstractEncoder() {
6678

6779
companion object {
6880
val validKeyKinds = setOf(PrimitiveKind.STRING, PrimitiveKind.CHAR, SerialKind.ENUM)
6981
val bsonValueCodec = BsonValueCodec()
82+
private val DOUBLE_MIN_VALUE = BigDecimal.valueOf(Double.MIN_VALUE)
83+
private val DOUBLE_MAX_VALUE = BigDecimal.valueOf(Double.MAX_VALUE)
84+
private val INT_MIN_VALUE = BigDecimal.valueOf(Int.MIN_VALUE.toLong())
85+
private val INT_MAX_VALUE = BigDecimal.valueOf(Int.MAX_VALUE.toLong())
86+
private val LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE)
87+
private val LONG_MAX_VALUE = BigDecimal.valueOf(Long.MAX_VALUE)
7088
}
7189

7290
private var isPolymorphic = false
7391
private var state = STATE.VALUE
7492
private var mapState = MapState()
7593
private var deferredElementName: String? = null
94+
override val json = Json {
95+
explicitNulls = configuration.explicitNulls
96+
encodeDefaults = configuration.encodeDefaults
97+
classDiscriminator = configuration.classDiscriminator
98+
serializersModule = this@DefaultBsonEncoder.serializersModule
99+
}
76100

77101
override fun shouldEncodeElementDefault(descriptor: SerialDescriptor, index: Int): Boolean =
78102
configuration.encodeDefaults
@@ -143,10 +167,10 @@ internal class DefaultBsonEncoder(
143167
deferredElementName?.let {
144168
if (value != null || configuration.explicitNulls) {
145169
encodeName(it)
146-
super.encodeNullableSerializableValue(serializer, value)
170+
super<AbstractEncoder>.encodeNullableSerializableValue(serializer, value)
147171
}
148172
}
149-
?: super.encodeNullableSerializableValue(serializer, value)
173+
?: super<AbstractEncoder>.encodeNullableSerializableValue(serializer, value)
150174
}
151175

152176
override fun encodeByte(value: Byte) = encodeInt(value.toInt())
@@ -183,8 +207,50 @@ internal class DefaultBsonEncoder(
183207
bsonValueCodec.encode(writer, value, EncoderContext.builder().build())
184208
}
185209

210+
override fun encodeJsonElement(element: JsonElement) = when(element) {
211+
is JsonNull -> encodeNull()
212+
is JsonPrimitive -> {
213+
val content = element.content
214+
when {
215+
element.isString -> encodeString(content)
216+
content == "true" || content == "false" ->
217+
encodeBoolean(content.toBooleanStrict())
218+
else -> {
219+
val decimal = BigDecimal(content)
220+
when {
221+
decimal.stripTrailingZeros().scale() > 0 &&
222+
DOUBLE_MIN_VALUE <= decimal && decimal <= DOUBLE_MAX_VALUE ->
223+
encodeDouble(element.double)
224+
INT_MIN_VALUE <= decimal && decimal <= INT_MAX_VALUE ->
225+
encodeInt(element.int)
226+
LONG_MIN_VALUE <= decimal && decimal <= LONG_MAX_VALUE ->
227+
encodeLong(element.long)
228+
else -> writer.writeDecimal128(Decimal128(decimal))
229+
}
230+
}
231+
}
232+
}
233+
is JsonObject -> encodeJsonObject(element)
234+
is JsonArray -> encodeJsonArray(element)
235+
}
236+
186237
override fun writer(): BsonWriter = writer
187238

239+
private fun encodeJsonObject(obj: JsonObject) {
240+
writer.writeStartDocument()
241+
obj.forEach { k, v ->
242+
writer.writeName(k)
243+
encodeJsonElement(v)
244+
}
245+
writer.writeEndDocument()
246+
}
247+
248+
private fun encodeJsonArray(array: JsonArray) {
249+
writer.writeStartArray()
250+
array.forEach(::encodeJsonElement)
251+
writer.writeEndArray()
252+
}
253+
188254
private fun encodeName(value: Any) {
189255
writer.writeName(value.toString())
190256
deferredElementName = null

0 commit comments

Comments
 (0)