diff --git a/driver-scala/src/main/scala/org/mongodb/scala/package.scala b/driver-scala/src/main/scala/org/mongodb/scala/package.scala index 95a1e415fbd..970f287786e 100644 --- a/driver-scala/src/main/scala/org/mongodb/scala/package.scala +++ b/driver-scala/src/main/scala/org/mongodb/scala/package.scala @@ -16,11 +16,14 @@ package org.mongodb -import _root_.scala.language.implicitConversions -import _root_.scala.reflect.ClassTag +import org.bson.BsonDocumentReader +import org.bson.codecs.{ DecoderContext, DocumentCodec } import org.mongodb.scala.bson.BsonDocument import org.mongodb.scala.internal.WriteConcernImplicits +import _root_.scala.language.implicitConversions +import _root_.scala.reflect.ClassTag + /** * The MongoDB Scala Driver package * @@ -392,9 +395,12 @@ package object scala extends ClientSessionImplicits with ObservableImplicits wit implicit def bsonDocumentToDocument(doc: BsonDocument): Document = new Document(doc) - implicit def bsonDocumentToUntypedDocument(doc: BsonDocument): org.bson.Document = - org.bson.Document.parse(doc.toJson()) + implicit def documentToUntypedDocument(doc: Document): org.bson.Document = + bsonDocumentToUntypedDocument(doc.underlying) - implicit def documentToUntypedDocument(doc: Document): org.bson.Document = org.bson.Document.parse(doc.toJson()) + private lazy val DOCUMENT_CODEC = new DocumentCodec() + implicit def bsonDocumentToUntypedDocument(doc: BsonDocument): org.bson.Document = { + DOCUMENT_CODEC.decode(new BsonDocumentReader(doc), DecoderContext.builder().build()) + } } diff --git a/driver-scala/src/test/scala/org/mongodb/scala/ScalaPackageSpec.scala b/driver-scala/src/test/scala/org/mongodb/scala/ScalaPackageSpec.scala index d89c58d3e26..3a91b8c3034 100644 --- a/driver-scala/src/test/scala/org/mongodb/scala/ScalaPackageSpec.scala +++ b/driver-scala/src/test/scala/org/mongodb/scala/ScalaPackageSpec.scala @@ -17,15 +17,14 @@ package org.mongodb.scala import java.util.concurrent.TimeUnit - import _root_.scala.concurrent.duration.Duration - import com.mongodb.{ MongoCredential => JMongoCredential } - +import org.bson.BsonDocumentWrapper +import org.bson.codecs.DocumentCodec import org.mongodb.scala -import org.mongodb.scala.bson.BsonString +import org.mongodb.scala.MongoClient.DEFAULT_CODEC_REGISTRY +import org.mongodb.scala.bson._ import org.mongodb.scala.model._ -import org.scalatest.{ FlatSpec, Matchers } class ScalaPackageSpec extends BaseSpec { @@ -66,9 +65,9 @@ class ScalaPackageSpec extends BaseSpec { it should "be able to create Documents" in { val doc = Document("a" -> BsonString("1")) - val doc2 = org.mongodb.scala.bson.collection.Document("a" -> BsonString("1")) + val doc2 = collection.Document("a" -> BsonString("1")) - doc shouldBe a[org.mongodb.scala.bson.collection.immutable.Document] + doc shouldBe a[collection.immutable.Document] doc should equal(doc2) } @@ -141,4 +140,33 @@ class ScalaPackageSpec extends BaseSpec { val javaCredential5 = JMongoCredential.createGSSAPICredential("userName") scalaCredential5 should equal(javaCredential5) } + + it should "implicitly convert to org.bson.document with type fidelity" in { + + val bsonDocument = Document( + "null" -> BsonNull(), + "int32" -> BsonInt32(32), + "int64" -> BsonInt64(Long.MaxValue), + "decimal128" -> BsonDecimal128(128.1), + "boolean" -> BsonBoolean(true), + "date" -> BsonDateTime(123456789), + "double" -> BsonDouble(1.1), + "string" -> BsonString("String"), + "minKey" -> BsonMinKey(), + "maxKey" -> BsonMaxKey(), + "javaScript" -> BsonJavaScript("function () {}"), + "objectId" -> BsonObjectId(), + "codeWithScope" -> BsonJavaScriptWithScope("function () {}", Document()), + "regex" -> BsonRegularExpression("/(.*)/"), + "symbol" -> BsonSymbol(Symbol("sym")), + "timestamp" -> BsonTimestamp(), + "undefined" -> BsonUndefined(), + "binary" -> BsonBinary(Array[Byte](128.toByte)), + "array" -> BsonArray(List("a", "b", "c")), + "document" -> Document("a" -> 1, "b" -> List(1, 2, 3)) + ) + + val document: org.bson.Document = bsonDocument + BsonDocumentWrapper.asBsonDocument(document, DEFAULT_CODEC_REGISTRY) should equal(bsonDocument.underlying) + } }