Skip to content

Commit

Permalink
Add UPickle integration
Browse files Browse the repository at this point in the history
  • Loading branch information
lloydmeta committed Aug 4, 2016
1 parent 0137458 commit abd4b5e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UPickler._
* Copyright 2016
*/

sealed trait UPickleValueEnum[ValueType <: AnyVal, EntryType <: ValueEnumEntry[ValueType]] { this: ValueEnum[ValueType, EntryType] =>
sealed trait UPickleValueEnum[ValueType, EntryType <: ValueEnumEntry[ValueType]] { this: ValueEnum[ValueType, EntryType] =>

/**
* Implicit UPickle ReadWriter
Expand Down Expand Up @@ -39,3 +39,10 @@ trait LongUPickleEnum[EntryType <: LongEnumEntry] extends UPickleValueEnum[Long,
trait ShortUPickleEnum[EntryType <: ShortEnumEntry] extends UPickleValueEnum[Short, EntryType] { this: ValueEnum[Short, EntryType] =>
implicit val uPickleReadWriter: RW[EntryType] = ReadWriter(writer(this).write, reader(this).read)
}

/**
* Enum implementation for String enum members that contains an implicit UPickle ReadWriter
*/
trait StringUPickleEnum[EntryType <: StringEnumEntry] extends UPickleValueEnum[String, EntryType] { this: ValueEnum[String, EntryType] =>
implicit val uPickleReadWriter: RW[EntryType] = ReadWriter(writer(this).write, reader(this).read)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object UPickler {
/**
* Returns a Reader for the given ValueEnum
*/
def reader[ValueType <: AnyVal: Reader, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Reader[EntryType] = {
def reader[ValueType: Reader, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Reader[EntryType] = {
val valueReader = implicitly[Reader[ValueType]]
Reader[EntryType] {
valueReader.read.andThenPartial { case v if enum.withValueOpt(v).isDefined => enum.withValue(v) }
Expand All @@ -23,7 +23,7 @@ object UPickler {
/**
* Returns a Writer for the given ValueEnum
*/
def writer[ValueType <: AnyVal: Writer, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Writer[EntryType] = {
def writer[ValueType: Writer, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Writer[EntryType] = {
val valueWriter = implicitly[Writer[ValueType]]
Writer[EntryType] {
case member => valueWriter.write(member.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ class UPicklerSpec extends FunSpec with Matchers {
testPickling("LongUPickleEnum", UPickleContentType)
testPickling("ShortUPickleEnum", UPickleDrinks)
testPickling("IntUPickleEnum", UPickleLibraryItem)
testPickling("StringUPickleEnum", UPickleOperatingSystem)
testPickling("IntUPickleEnum with values declared as members", UPickleMovieGenre)

/**
* Given an enum, tests its JSON reading and writing behaviour, grouping the test results under the given enumKind descriptor
*/
private def testPickling[ValueType <: AnyVal: Writer: Numeric, EntryType <: ValueEnumEntry[ValueType]: Reader: Writer](enumKind: String, enum: UPickleValueEnum[ValueType, EntryType] with ValueEnum[ValueType, EntryType]) = {
private def testPickling[ValueType: Writer, EntryType <: ValueEnumEntry[ValueType]: Reader: Writer](enumKind: String, enum: UPickleValueEnum[ValueType, EntryType] with ValueEnum[ValueType, EntryType]) = {
describe(enumKind) {
describe("Reader") {

Expand All @@ -44,7 +45,6 @@ class UPicklerSpec extends FunSpec with Matchers {
describe("Writer") {

it("should write enum values to JS") {
val numeric = implicitly[Numeric[ValueType]]
val valueTypeWriter = implicitly[Writer[ValueType]]
enum.values.foreach { entry =>
writeJs(entry) shouldBe valueTypeWriter.write(entry.value)
Expand Down Expand Up @@ -99,6 +99,19 @@ case object UPickleLibraryItem extends IntEnum[UPickleLibraryItem] with IntUPick

}

sealed abstract class UPickleOperatingSystem(val value: String) extends StringEnumEntry

case object UPickleOperatingSystem extends StringEnum[UPickleOperatingSystem] with StringUPickleEnum[UPickleOperatingSystem] {

case object Linux extends UPickleOperatingSystem("linux")
case object OSX extends UPickleOperatingSystem("osx")
case object Windows extends UPickleOperatingSystem("windows")
case object Android extends UPickleOperatingSystem("android")

val values = findValues

}

sealed abstract class UPickleMovieGenre extends IntEnumEntry

case object UPickleMovieGenre extends IntEnum[UPickleMovieGenre] with IntUPickleEnum[UPickleMovieGenre] {
Expand Down

0 comments on commit abd4b5e

Please sign in to comment.