Skip to content

Commit

Permalink
Refactor ReactiveMongo code
Browse files Browse the repository at this point in the history
- Optimise Reading BSON values
- Rename handler to bsonHandler for consistency
- Add check for convertable to Short
  • Loading branch information
lloydmeta committed May 3, 2016
1 parent b1a8cd4 commit 11e52c9
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import reactivemongo.bson.{ BSONHandler, BSONInteger, BSONLong, BSONReader, BSON
*/
object BSONValueHandlers extends BSONValueReads with BSONValueWrites {

implicit def bsonHandler[A](implicit reader: BSONReader[BSONValue, A], writer: BSONWriter[A, BSONValue]) = new BSONHandler[BSONValue, A] {
implicit def anyBsonHandler[A](implicit reader: BSONReader[BSONValue, A], writer: BSONWriter[A, BSONValue]) = new BSONHandler[BSONValue, A] {
def write(t: A): BSONValue = writer.write(t)
def read(bson: BSONValue): A = reader.read(bson)
}
Expand All @@ -25,7 +25,7 @@ trait BSONValueReads {

implicit val bsonReaderShort = new BSONReader[BSONValue, Short] {
override def read(bson: BSONValue): Short = bson match {
case BSONInteger(x) => x.toShort
case BSONInteger(x) if Short.MaxValue >= x && Short.MinValue <= x => x.toShort
case _ => throw new RuntimeException(s"Could not convert $bson to Short")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,8 @@ object EnumHandler {
*/
def reader[ValueType <: AnyVal, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType])(implicit baseBsonReader: BSONReader[BSONValue, ValueType]): BSONReader[BSONValue, EntryType] = new BSONReader[BSONValue, EntryType] {
override def read(bson: BSONValue): EntryType = {
val result: Try[EntryType] = baseBsonReader.readTry(bson).flatMap { s =>
val maybeBound = enum.withValueOpt(s)
maybeBound match {
case Some(obj) => Success(obj)
case None => Failure(
new RuntimeException(s"Enumeration expected of type: '$enum', but it does not appear to contain the value: '$s'")
)
}
}

result.get
val value = baseBsonReader.read(bson)
enum.withValue(value)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ sealed trait ReactiveMongoBsonValueEnum[ValueType <: AnyVal, EntryType <: ValueE
/**
* Implicit BSON handler for the entries of this enum
*/
implicit def handler: BSONHandler[BSONValue, EntryType]
implicit def bsonHandler: BSONHandler[BSONValue, EntryType]
}

/**
Expand All @@ -23,7 +23,7 @@ sealed trait ReactiveMongoBsonValueEnum[ValueType <: AnyVal, EntryType <: ValueE
trait IntReactiveMongoBsonValueEnum[EntryType <: IntEnumEntry] extends ReactiveMongoBsonValueEnum[Int, EntryType] {
this: IntEnum[EntryType] =>

implicit val handler: BSONHandler[BSONValue, EntryType] = EnumHandler.handler(this)
implicit val bsonHandler: BSONHandler[BSONValue, EntryType] = EnumHandler.handler(this)
}

/**
Expand All @@ -32,7 +32,7 @@ trait IntReactiveMongoBsonValueEnum[EntryType <: IntEnumEntry] extends ReactiveM
trait LongReactiveMongoBsonValueEnum[EntryType <: LongEnumEntry] extends ReactiveMongoBsonValueEnum[Long, EntryType] {
this: LongEnum[EntryType] =>

implicit val handler: BSONHandler[BSONValue, EntryType] = EnumHandler.handler(this)
implicit val bsonHandler: BSONHandler[BSONValue, EntryType] = EnumHandler.handler(this)
}

/**
Expand All @@ -41,5 +41,5 @@ trait LongReactiveMongoBsonValueEnum[EntryType <: LongEnumEntry] extends Reactiv
trait ShortReactiveMongoBsonValueEnum[EntryType <: ShortEnumEntry] extends ReactiveMongoBsonValueEnum[Short, EntryType] {
this: ShortEnum[EntryType] =>

implicit val handler: BSONHandler[BSONValue, EntryType] = EnumHandler.handler(this)
implicit val bsonHandler: BSONHandler[BSONValue, EntryType] = EnumHandler.handler(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ class EnumBsonHandlerSpec extends FunSpec with Matchers with EnumBsonHandlerHelp
testHandler("IntEnum", LibraryItem)
testHandler("LongEnum", ContentType)
testHandler("ShortEnum", Drinks)
testHandler("ShortReactiveMongoBsonValueEnum", BsonDrinks, Some(BsonDrinks.handler))
testHandler("LongReactiveMongoBsonValueEnum", BsonContentType, Some(BsonContentType.handler))
testHandler("IntReactiveMongoBsonValueEnum", BsonLibraryItem, Some(BsonLibraryItem.handler))
testHandler("ShortReactiveMongoBsonValueEnum", BsonDrinks, Some(BsonDrinks.bsonHandler))
testHandler("LongReactiveMongoBsonValueEnum", BsonContentType, Some(BsonContentType.bsonHandler))
testHandler("IntReactiveMongoBsonValueEnum", BsonLibraryItem, Some(BsonLibraryItem.bsonHandler))

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,11 @@ object EnumHandler {
def reader[A <: EnumEntry](enum: Enum[A], insensitive: Boolean = false): BSONReader[BSONValue, A] =
new BSONReader[BSONValue, A] {
override def read(bson: BSONValue): A = {
val result = bson match {
case BSONString(s) => {
val maybeBound = if (insensitive) enum.withNameInsensitiveOption(s) else enum.withNameOption(s)
maybeBound match {
case Some(obj) => Success(obj)
case None => Failure(new RuntimeException(
s"Enumeration expected of type: '$enum', but it does not appear to contain the value: '$s'"
))
}
}
case _ => Failure(new RuntimeException("String value expected"))
bson match {
case BSONString(s) if insensitive => enum.withNameInsensitive(s)
case BSONString(s) => enum.withName(s)
case _ => throw new RuntimeException("String value expected")
}

result.get
}
}

Expand Down

0 comments on commit 11e52c9

Please sign in to comment.