Skip to content

Commit

Permalink
Merge e7654af into 2c9b731
Browse files Browse the repository at this point in the history
  • Loading branch information
olsio committed Dec 16, 2019
2 parents 2c9b731 + e7654af commit f80207f
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 182 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Integrations are available for:
- [Play](https://www.playframework.com/): JVM only
- [Play JSON](https://www.playframework.com/documentation/2.5.x/ScalaJson): JVM (included in Play integration but also available separately) and ScalaJS
- [Circe](https://github.com/travisbrown/circe): JVM and ScalaJS
- [ReactiveMongo BSON](http://reactivemongo.org/releases/0.11/documentation/bson/overview.html): JVM only
- [ReactiveMongo BSON](http://reactivemongo.org/releases/0.1x/documentation/bson/overview.html): JVM only
- [Argonaut](http://argonaut.io): JVM and ScalaJS
- [Json4s](http://json4s.org): JVM only
- [ScalaCheck](https://www.scalacheck.org): JVM and ScalaJS
Expand Down Expand Up @@ -662,16 +662,16 @@ case object BsonDrinks extends ShortEnum[BsonDrinks] with ShortReactiveMongoBson

}

import reactivemongo.bson._
import reactivemongo.api.bson._

// Use to deserialise numbers to enum members directly
BsonDrinks.values.foreach { drink =>
val writer = implicitly[BSONWriter[BsonDrinks, BSONValue]]
val writer = implicitly[BSONWriter[BsonDrinks]]

assert(writer.write(drink) == BSONInteger(drink.value))
}

val reader = implicitly[BSONReader[BSONValue, BsonDrinks]]
val reader = implicitly[BSONReader[BsonDrinks]]

assert(reader.read(BSONInteger(3)) == BsonDrinks.Cola)
```
Expand Down
6 changes: 3 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import com.typesafe.sbt.SbtGit.{GitKeys => git}
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
import sbtbuildinfo.BuildInfoPlugin.autoImport._
import sbtcrossproject.CrossPlugin.autoImport.{CrossType, crossProject}

lazy val theScalaVersion = "2.12.8"

Expand All @@ -17,7 +17,7 @@ lazy val scalaTestVersion = "3.0.8"
lazy val scalacheckVersion = "1.14.0"

// Library versions
lazy val reactiveMongoVersion = "0.18.6"
lazy val reactiveMongoVersion = "0.19.4"
lazy val argonautVersion = "6.2.3"
lazy val json4sVersion = "3.6.6"
lazy val quillVersion = "3.5.0"
Expand Down Expand Up @@ -261,7 +261,7 @@ lazy val enumeratumReactiveMongoBson =
.settings(testSettings: _*)
.settings(
version := "1.5.15-SNAPSHOT",
crossScalaVersions := scalaVersionsAll,
crossScalaVersions := post210Only(scalaVersionsAll),
libraryDependencies ++= Seq(
"org.reactivemongo" %% "reactivemongo" % reactiveMongoVersion,
"com.beachape" %% "enumeratum" % Versions.Core.stable,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package enumeratum

import reactivemongo.bson._
import reactivemongo.api.bson._

import scala.util.{Failure, Try}

/**
* Holds BSON reader and writer for [[enumeratum.Enum]]
Expand All @@ -20,69 +22,61 @@ 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 = {
): BSONReader[A] =
new BSONReader[A] {
override def readTry(bson: BSONValue): Try[A] =
bson match {
case BSONString(s) if insensitive => enum.withNameInsensitive(s)
case BSONString(s) => enum.withName(s)
case _ => throw new RuntimeException("String value expected")
case BSONString(s) if insensitive => Try(enum.withNameInsensitive(s))
case BSONString(s) => Try(enum.withName(s))
case _ => Failure(new RuntimeException("String value expected"))
}
}
}

/**
* Returns a BSONReader for a given enum [[Enum]] transformed to lower case
*
* @param enum The enum
*/
def readerLowercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONReader[BSONValue, A] =
new BSONReader[BSONValue, A] {
override def read(bson: BSONValue): A = {
bson match {
case BSONString(s) => enum.withNameLowercaseOnly(s)
case _ => throw new RuntimeException("String value expected")
}
}
def readerLowercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONReader[A] = new BSONReader[A] {
override def readTry(bson: BSONValue): Try[A] = bson match {
case BSONString(s) => Try(enum.withNameLowercaseOnly(s))
case _ => Failure(new RuntimeException("String value expected"))
}
}

/**
* Returns a BSONReader for a given enum [[Enum]] transformed to upper case
*
* @param enum The enum
*/
def readerUppercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONReader[BSONValue, A] =
new BSONReader[BSONValue, A] {
override def read(bson: BSONValue): A = {
bson match {
case BSONString(s) => enum.withNameUppercaseOnly(s)
case _ => throw new RuntimeException("String value expected")
}
def readerUppercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONReader[A] = new BSONReader[A] {
override def readTry(bson: BSONValue): Try[A] =
bson match {
case BSONString(s) => Try(enum.withNameUppercaseOnly(s))
case _ => Failure(new RuntimeException("String value expected"))
}
}
}

/**
* Returns a BSONWriter for a given enum [[Enum]]
*/
def writer[A <: EnumEntry](enum: Enum[A]): BSONWriter[A, BSONValue] =
new BSONWriter[A, BSONValue] {
override def write(t: A): BSONValue = BSONString(t.entryName)
}
def writer[A <: EnumEntry](enum: Enum[A]): BSONWriter[A] = new BSONWriter[A] {
override def writeTry(t: A): Try[BSONValue] = Try(BSONString(t.entryName))
}

/**
* Returns a BSONWriter for a given enum [[Enum]], outputting the value as lower case
*/
def writerLowercase[A <: EnumEntry](enum: Enum[A]): BSONWriter[A, BSONValue] =
new BSONWriter[A, BSONValue] {
override def write(t: A): BSONValue = BSONString(t.entryName.toLowerCase)
}
def writerLowercase[A <: EnumEntry](enum: Enum[A]): BSONWriter[A] = new BSONWriter[A] {
override def writeTry(t: A): Try[BSONValue] = Try(BSONString(t.entryName.toLowerCase))
}

/**
* Returns a BSONWriter for a given enum [[Enum]], outputting the value as upper case
*/
def writerUppercase[A <: EnumEntry](enum: Enum[A]): BSONWriter[A, BSONValue] =
new BSONWriter[A, BSONValue] {
override def write(t: A): BSONValue = BSONString(t.entryName.toUpperCase)
def writerUppercase[A <: EnumEntry](enum: Enum[A]): BSONWriter[A] =
new BSONWriter[A] {
override def writeTry(t: A): Try[BSONValue] = Try(BSONString(t.entryName.toUpperCase))
}

/**
Expand All @@ -94,43 +88,43 @@ object EnumHandler {
def handler[A <: EnumEntry](
enum: Enum[A],
insensitive: Boolean = false
): BSONHandler[BSONValue, A] =
new BSONHandler[BSONValue, A] {
): BSONHandler[A] =
new BSONHandler[A] {
private val concreteReader = reader(enum, insensitive)
private val concreteWriter = writer(enum)

override def read(bson: BSONValue): A = concreteReader.read(bson)
override def readTry(bson: BSONValue): Try[A] = concreteReader.readTry(bson)

override def write(t: A): BSONValue = concreteWriter.write(t)
override def writeTry(t: A): Try[BSONValue] = concreteWriter.writeTry(t)
}

/**
* Returns a BSONHandler for a given enum [[Enum]], handling a lower case transformation
*
* @param enum The enum
*/
def handlerLowercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONHandler[BSONValue, A] =
new BSONHandler[BSONValue, A] {
def handlerLowercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONHandler[A] =
new BSONHandler[A] {
private val concreteReader = readerLowercaseOnly(enum)
private val concreteWriter = writerLowercase(enum)

override def read(bson: BSONValue): A = concreteReader.read(bson)
override def readTry(bson: BSONValue): Try[A] = concreteReader.readTry(bson)

override def write(t: A): BSONValue = concreteWriter.write(t)
override def writeTry(t: A): Try[BSONValue] = concreteWriter.writeTry(t)
}

/**
* Returns a BSONHandler for a given enum [[Enum]], handling an upper case transformation
*
* @param enum The enum
*/
def handlerUppercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONHandler[BSONValue, A] =
new BSONHandler[BSONValue, A] {
def handlerUppercaseOnly[A <: EnumEntry](enum: Enum[A]): BSONHandler[A] =
new BSONHandler[A] {
private val concreteReader = readerUppercaseOnly(enum)
private val concreteWriter = writerUppercase(enum)

override def read(bson: BSONValue): A = concreteReader.read(bson)
override def readTry(bson: BSONValue): Try[A] = concreteReader.readTry(bson)

override def write(t: A): BSONValue = concreteWriter.write(t)
override def writeTry(t: A): Try[BSONValue] = concreteWriter.writeTry(t)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package enumeratum

import reactivemongo.bson._
import reactivemongo.api.bson.BSONHandler

/**
* @author Alessandro Lacava (@lambdista)
* @since 2016-04-23
*/
trait ReactiveMongoBsonEnum[A <: EnumEntry] { self: Enum[A] =>
implicit val bsonHandler: BSONHandler[BSONValue, A] =
implicit val bsonHandler: BSONHandler[A] =
EnumHandler.handler(this)
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
package enumeratum.values

import reactivemongo.bson.{
BSONHandler,
BSONInteger,
BSONLong,
BSONReader,
BSONString,
BSONValue,
BSONWriter
}
import reactivemongo.api.bson.{BSONHandler, BSONInteger, BSONLong, BSONString, BSONValue}

import scala.util.{Failure, Try}

/**
* Created by Lloyd on 5/3/16.
Expand All @@ -19,93 +13,59 @@ import reactivemongo.bson.{
* Holds BSONValue to implicits. The ones that come with ReactiveMongo by default are for subclasses like BSONLong,
* but what we want are BSONValue and the Reader/Writer/Handler typeclasses are not covariant.
*/
object BSONValueHandlers extends BSONValueReads with BSONValueWrites {
object BSONValueHandlers {

@SuppressWarnings(Array("org.wartremover.warts.ExplicitImplicitTypes")) // False alarm
implicit def anyBsonHandler[A](implicit reader: BSONReader[BSONValue, A],
writer: BSONWriter[A, BSONValue]): BSONHandler[BSONValue, A] =
new BSONHandler[BSONValue, A] {
def write(t: A): BSONValue = writer.write(t)
implicit def shortHandler: BSONHandler[Short] = new BSONHandler[Short] {
override def writeTry(t: Short): Try[BSONValue] = Try(BSONInteger(t.toInt))

def read(bson: BSONValue): A = reader.read(bson)
override def readTry(bson: BSONValue): Try[Short] = bson match {
case BSONInteger(x) if x.abs <= Short.MaxValue => Try(x.toShort)
case _ => Failure(new RuntimeException(s"Could not convert $bson to Short"))
}
}

}

@SuppressWarnings(Array("org.wartremover.warts.Throw"))
trait BSONValueReads {
implicit def intHandler: BSONHandler[Int] = new BSONHandler[Int] {
override def writeTry(t: Int): Try[BSONValue] = Try(BSONInteger(t))

implicit val bsonReaderShort: BSONReader[BSONValue, Short] = new BSONReader[BSONValue, Short] {
def read(bson: BSONValue): Short = bson match {
case BSONInteger(x) if x.abs <= Short.MaxValue => x.toShort
case _ => throw new RuntimeException(s"Could not convert $bson to Short")
override def readTry(bson: BSONValue): Try[Int] = bson match {
case BSONInteger(x) => Try(x)
case _ => Failure(new RuntimeException(s"Could not convert $bson to Int"))
}
}

implicit val bsonReaderInt: BSONReader[BSONValue, Int] = new BSONReader[BSONValue, Int] {
def read(bson: BSONValue): Int = bson match {
case BSONInteger(x) => x
case _ => throw new RuntimeException(s"Could not convert $bson to Int")
}
}
implicit def longHandler: BSONHandler[Long] = new BSONHandler[Long] {
override def writeTry(t: Long): Try[BSONValue] = Try(BSONLong(t))

implicit val bsonReaderLong: BSONReader[BSONValue, Long] = new BSONReader[BSONValue, Long] {
def read(bson: BSONValue): Long = bson match {
case BSONLong(x) => x
case _ => throw new RuntimeException(s"Could not convert $bson to Long")
override def readTry(bson: BSONValue): Try[Long] = bson match {
case BSONLong(x) => Try(x)
case _ => Failure(new RuntimeException(s"Could not convert $bson to Long"))
}
}

implicit val bsonReaderString: BSONReader[BSONValue, String] =
new BSONReader[BSONValue, String] {
def read(bson: BSONValue): String = bson match {
case BSONString(x) => x
case _ =>
throw new RuntimeException(s"Could not convert $bson to String")
}
}
implicit def stringHandler: BSONHandler[String] = new BSONHandler[String] {
override def writeTry(t: String): Try[BSONValue] = Try(BSONString(t))

implicit val bsonReaderChar: BSONReader[BSONValue, Char] = new BSONReader[BSONValue, Char] {
def read(bson: BSONValue): Char = bson match {
case BSONString(x) if x.length == 1 => x.charAt(0)
case _ => throw new RuntimeException(s"Could not convert $bson to Char")
override def readTry(bson: BSONValue): Try[String] = bson match {
case BSONString(x) => Try(x)
case _ => Failure(new RuntimeException(s"Could not convert $bson to String"))
}
}

implicit val bsonReaderByte: BSONReader[BSONValue, Byte] = new BSONReader[BSONValue, Byte] {
def read(bson: BSONValue): Byte = bson match {
case BSONInteger(x) if x.abs <= Byte.MaxValue => x.toByte
case _ => throw new RuntimeException(s"Could not convert $bson to Byte")
}
}
implicit def charHandler: BSONHandler[Char] = new BSONHandler[Char] {
override def writeTry(t: Char): Try[BSONValue] = Try(BSONString(s"$t"))

}

trait BSONValueWrites {

implicit val bsonWriterShort: BSONWriter[Short, BSONValue] = new BSONWriter[Short, BSONValue] {
def write(t: Short): BSONValue = BSONInteger(t.toInt)
}

implicit val bsonWriterInt: BSONWriter[Int, BSONValue] = new BSONWriter[Int, BSONValue] {
def write(t: Int): BSONValue = BSONInteger(t)
override def readTry(bson: BSONValue): Try[Char] = bson match {
case BSONString(x) if x.length == 1 => Try(x.charAt(0))
case _ => Failure(new RuntimeException(s"Could not convert $bson to Char"))
}
}

implicit val bsonWriterLong: BSONWriter[Long, BSONValue] = new BSONWriter[Long, BSONValue] {
def write(t: Long): BSONValue = BSONLong(t)
}
implicit def byteHandler: BSONHandler[Byte] = new BSONHandler[Byte] {
override def writeTry(t: Byte): Try[BSONValue] = Try(BSONInteger(t.toInt))

implicit val bsonWriterString: BSONWriter[String, BSONValue] =
new BSONWriter[String, BSONValue] {
def write(t: String): BSONValue = BSONString(t)
override def readTry(bson: BSONValue): Try[Byte] = bson match {
case BSONInteger(x) if x.abs <= Byte.MaxValue => Try(x.toByte)
case _ => Failure(new RuntimeException(s"Could not convert $bson to Byte"))
}

implicit val bsonWriterChar: BSONWriter[Char, BSONValue] = new BSONWriter[Char, BSONValue] {
def write(t: Char): BSONValue = BSONString(s"$t")
}

implicit val bsonWriterByte: BSONWriter[Byte, BSONValue] = new BSONWriter[Byte, BSONValue] {
def write(t: Byte): BSONValue = BSONInteger(t.toInt)
}

}
Loading

0 comments on commit f80207f

Please sign in to comment.