Skip to content

Commit

Permalink
Add Circe integration
Browse files Browse the repository at this point in the history
  • Loading branch information
lloydmeta committed Aug 4, 2016
1 parent ec227a1 commit 1273b4f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object Circe {
/**
* Returns an Encoder for the provided ValueEnum
*/
def encoder[ValueType <: AnyVal: Encoder, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Encoder[EntryType] = {
def encoder[ValueType: Encoder, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Encoder[EntryType] = {
new Encoder[EntryType] {
private val valueEncoder = implicitly[Encoder[ValueType]]
def apply(a: EntryType): Json = valueEncoder.apply(a.value)
Expand All @@ -24,7 +24,7 @@ object Circe {
/**
* Returns a Decoder for the provided ValueEnum
*/
def decoder[ValueType <: AnyVal: Decoder, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Decoder[EntryType] = {
def decoder[ValueType: Decoder, EntryType <: ValueEnumEntry[ValueType]](enum: ValueEnum[ValueType, EntryType]): Decoder[EntryType] = {
new Decoder[EntryType] {
private val valueDecoder = implicitly[Decoder[ValueType]]
def apply(c: HCursor): Result[EntryType] = valueDecoder.apply(c).flatMap { v =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.circe.{ Decoder, Encoder }
* Copyright 2016
*/

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

/**
Expand Down Expand Up @@ -45,3 +45,11 @@ trait ShortCirceEnum[EntryType <: ShortEnumEntry] extends CirceValueEnum[Short,
implicit val circeEncoder = Circe.encoder(this)
implicit val circeDecoder = Circe.decoder(this)
}

/**
* CirceEnum for StringEnumEntry
*/
trait StringCirceEnum[EntryType <: StringEnumEntry] extends CirceValueEnum[String, EntryType] { this: ValueEnum[String, EntryType] =>
implicit val circeEncoder = Circe.encoder(this)
implicit val circeDecoder = Circe.decoder(this)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ class CirceValueEnumSpec extends FunSpec with Matchers {
testCirceEnum("LongCirceEnum", CirceContentType)
testCirceEnum("ShortCirceEnum", CirceDrinks)
testCirceEnum("IntCirceEnum", CirceLibraryItem)
testCirceEnum("StringCirceEnum", CirceOperatingSystem)
testCirceEnum("IntCirceEnum with val value members", CirceMovieGenre)

// Test method that generates tests for most primitve-based ValueEnums when given a simple descriptor and the enum
private def testCirceEnum[ValueType <: AnyVal: Encoder: Decoder, EntryType <: ValueEnumEntry[ValueType]: Encoder: Decoder](enumKind: String, enum: ValueEnum[ValueType, EntryType] with CirceValueEnum[ValueType, EntryType]): Unit = {
private def testCirceEnum[ValueType: Encoder: Decoder, EntryType <: ValueEnumEntry[ValueType]: Encoder: Decoder](enumKind: String, enum: ValueEnum[ValueType, EntryType] with CirceValueEnum[ValueType, EntryType]): Unit = {
describe(enumKind) {

describe("to JSON") {
Expand Down Expand Up @@ -93,6 +94,19 @@ case object CirceLibraryItem extends IntEnum[CirceLibraryItem] with IntCirceEnum

}

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

case object CirceOperatingSystem extends StringEnum[CirceOperatingSystem] with StringCirceEnum[CirceOperatingSystem] {

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

val values = findValues

}

sealed abstract class CirceMovieGenre extends IntEnumEntry

case object CirceMovieGenre extends IntEnum[CirceMovieGenre] with IntCirceEnum[CirceMovieGenre] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ class ValueEnumSpec extends FunSpec with Matchers with ValueEnumHelpers {
companion.values should contain(ContentType.Audio)
}

it("should work for StringEnum") {
def findCompanion[EntryType <: StringEnumEntry: StringEnum](entry: EntryType) = implicitly[StringEnum[EntryType]]
val companion = findCompanion(OperatingSystem.Android: OperatingSystem)
companion shouldBe OperatingSystem
companion.values should contain(OperatingSystem.Windows)
}

}

describe("compilation failures") {
Expand Down

0 comments on commit 1273b4f

Please sign in to comment.