diff --git a/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonCollectionFormats.scala b/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonCollectionFormats.scala index ffc7c6f..d950d70 100644 --- a/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonCollectionFormats.scala +++ b/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonCollectionFormats.scala @@ -31,6 +31,25 @@ trait BsonCollectionFormats extends TraversableLikeFormats { override def defaultValue: Set[T] = Set.empty[T] } + implicit def seqFormat[T: BsonFormat]: BsonFormat[Seq[T]] = new BsonFormat[Seq[T]] with BsonArrayReader[Seq[T]] { + + private[this] implicit val f = implicitly[BsonFormat[T]] + + def write(in: Seq[T]): BsonArray = { + new BsonArray(in.map(f.write).asJava) + } + + def read(value: BsonValue): Seq[T] = { + val list: Seq[BsonValue] = if (value.isNull) Seq.empty[BsonValue] + else value.asArray().asScala.toSeq + list.map(f.read) + } + + override def flds: Map[String, BsonFormat[_]] = f.flds + + override def defaultValue: Seq[T] = Seq.empty[T] + } + implicit def arrayFormat[T: BsonFormat: ClassTag] = new BsonFormat[Array[T]] with BsonArrayReader[Array[T]] { implicit val f = implicitly[BsonFormat[T]] def write(array: Array[T]) = { diff --git a/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonFormats.scala b/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonFormats.scala index 7d3c0d9..9d89e10 100644 --- a/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonFormats.scala +++ b/bsonshapeless/src/main/scala/me/sgrouples/rogue/BsonFormats.scala @@ -261,7 +261,43 @@ trait BaseBsonFormats { trait StandardBsonFormats extends BaseBsonFormats with BsonCollectionFormats with MapKeyFormats -object BsonFormats extends StandardBsonFormats with BsonFormats +object BsonFormats extends StandardBsonFormats with BsonFormats { + // Default BsonFormat[Option[T]] formats + implicit val optionalBooleanBsonFormat: BsonFormat[Option[Boolean]] = optionFormat + implicit val optionalIntBsonFormat: BsonFormat[Option[Int]] = optionFormat + implicit val optionalLongBsonFormat: BsonFormat[Option[Long]] = optionFormat + implicit val optionalStringBsonFormat: BsonFormat[Option[String]] = optionFormat + implicit val optionalCurrencyBsonFormat: BsonFormat[Option[Currency]] = optionFormat + implicit val optionalUUIDBsonFormat: BsonFormat[Option[UUID]] = optionFormat + implicit val optionalTimeZoneBsonFormat: BsonFormat[Option[TimeZone]] = optionFormat + implicit val optionalLocalDateTimeBsonFormat: BsonFormat[Option[LocalDateTime]] = optionFormat + implicit val optionalInstantBsonFormat: BsonFormat[Option[Instant]] = optionFormat + implicit val optionalBinaryBsonFormat: BsonFormat[Option[Array[Byte]]] = optionFormat + implicit val optionalObjectIdBsonFormat: BsonFormat[Option[ObjectId]] = optionFormat + + // Default BsonFormat[Seq[T]] formats + implicit val booleansBsonFormat: BsonFormat[Seq[Boolean]] = seqFormat + implicit val intsBsonFormat: BsonFormat[Seq[Int]] = seqFormat + implicit val longsBsonFormat: BsonFormat[Seq[Long]] = seqFormat + implicit val stringsBsonFormat: BsonFormat[Seq[String]] = seqFormat + implicit val currenciesBsonFormat: BsonFormat[Seq[Currency]] = seqFormat + implicit val uuidsBsonFormat: BsonFormat[Seq[UUID]] = seqFormat + implicit val timeZonesBsonFormat: BsonFormat[Seq[TimeZone]] = seqFormat + implicit val localDatesTimeBsonFormat: BsonFormat[Seq[LocalDateTime]] = seqFormat + implicit val instantsBsonFormat: BsonFormat[Seq[Instant]] = seqFormat + implicit val objectIdsBsonFormat: BsonFormat[Seq[ObjectId]] = seqFormat + + // Default BsonFormat[Seq[T]] formats + implicit val optionalBooleansBsonFormat: BsonFormat[Option[Seq[Boolean]]] = optionFormat + implicit val optionalIntsBsonFormat: BsonFormat[Option[Seq[Int]]] = optionFormat + implicit val optionalLongsBsonFormat: BsonFormat[Option[Seq[Long]]] = optionFormat + implicit val optionalStringsBsonFormat: BsonFormat[Option[Seq[String]]] = optionFormat + implicit val optionalUUIDsBsonFormat: BsonFormat[Option[Seq[UUID]]] = optionFormat + implicit val optionalTimeZonesBsonFormat: BsonFormat[Option[Seq[TimeZone]]] = optionFormat + implicit val optionalLocalDatesTimeBsonFormat: BsonFormat[Option[Seq[LocalDateTime]]] = optionFormat + implicit val optionalInstantsBsonFormat: BsonFormat[Option[Seq[Instant]]] = optionFormat + implicit val optionalObjectIdsBsonFormat: BsonFormat[Option[Seq[ObjectId]]] = optionFormat +} trait BsonFormats extends LowPrioBsonFormats { this: StandardBsonFormats => @@ -390,13 +426,13 @@ trait LowPrioBsonFormats { implicit def bsonEncoder[T, Repr](implicit gen: LabelledGeneric.Aux[T, Repr], - sg: Cached[Strict[WrappedBsonFromat[T, Repr]]], + sg: Cached[WrappedBsonFromat[T, Repr]], d: Default.AsRecord[T], tpe: Typeable[T]): BsonFormat[T] = new BsonFormat[T] with BsonArrayReader[T] { - override def write(t: T): BsonValue = sg.value.value.write(gen.to(t)) - override def read(b: BsonValue): T = gen.from(sg.value.value.read(b)) + override def write(t: T): BsonValue = sg.value.write(gen.to(t)) + override def read(b: BsonValue): T = gen.from(sg.value.read(b)) - override val flds: Map[String, BsonFormat[_]] = sg.value.value.flds + override val flds: Map[String, BsonFormat[_]] = sg.value.flds /** * for nested case classes, with default constructors provides a default value diff --git a/project/RogueSettings.scala b/project/RogueSettings.scala index 1806711..fb92f11 100644 --- a/project/RogueSettings.scala +++ b/project/RogueSettings.scala @@ -38,7 +38,7 @@ object RogueSettings { commands += Command.single("testOnlyUntilFailed") { (state, param) => s"testOnly $param" :: s"testOnlyUntilFailed $param" :: state }, - version := "5.3.0", + version := "5.4.0", organization := "me.sgrouples", scalaVersion := "2.13.1", crossScalaVersions := Seq("2.12.10", "2.13.1"),