Vulcan Vulcan

enumeratum

The vulcan-enumeratum module provides Codecs for Enumeratum enumerations.

Getting Started

To get started with sbt, add the following line to your build.sbt file.

libraryDependencies += "com.github.fd4s" %% "vulcan-enumeratum" % "1.14.1"

Usage

For regular Enums, also mix in VulcanEnum to derive a Codec instance.

import enumeratum.{Enum, EnumEntry, VulcanEnum}
import enumeratum.EnumEntry.Lowercase
import vulcan.Codec
import vulcan.generic.{AvroDoc, AvroNamespace}

@AvroNamespace("com.example")
@AvroDoc("The different card suits")
sealed trait Suit extends EnumEntry with Lowercase

object Suit extends Enum[Suit] with VulcanEnum[Suit] {
  case object Clubs extends Suit
  case object Diamonds extends Suit
  case object Hearts extends Suit
  case object Spades extends Suit

  val values = findValues
}

Codec[Suit]
// res1: Codec[Suit] = WithTypeName(
//   codec = Validated(
//     codec = Codec({
//   "type" : "enum",
//   "name" : "Suit",
//   "namespace" : "com.example",
//   "doc" : "The different card suits",
//   "symbols" : [ "clubs", "diamonds", "hearts", "spades" ]
// }),
//     validSchema = {"type":"enum","name":"Suit","namespace":"com.example","doc":"The different card suits","symbols":["clubs","diamonds","hearts","spades"]}
//   ),
//   typeName = "com.example.Suit"
// )

Annotations like @AvroDoc can be used to customize the derivation.

For ValueEnums, also mix in the matching VulcanValueEnum to derive a Codec instance.

import enumeratum.values.{StringEnum, StringEnumEntry, StringVulcanEnum}

@AvroNamespace("com.example")
@AvroDoc("The available colors")
sealed abstract class Color(val value: String) extends StringEnumEntry

object Color extends StringEnum[Color] with StringVulcanEnum[Color] {
  case object Red extends Color("red")
  case object Green extends Color("green")
  case object Blue extends Color("blue")

  val values = findValues
}

Codec[Color]
// res2: Codec.Aux[vulcan.Avro.EnumSymbol, Color] = WithTypeName(
//   codec = Validated(
//     codec = Codec({
//   "type" : "enum",
//   "name" : "Color",
//   "namespace" : "com.example",
//   "doc" : "The available colors",
//   "symbols" : [ "red", "green", "blue" ]
// }),
//     validSchema = {"type":"enum","name":"Color","namespace":"com.example","doc":"The available colors","symbols":["red","green","blue"]}
//   ),
//   typeName = "com.example.Color"
// )

For StringVulcanEnum, the enumeration is encoded as an Avro enumeration. For the other VulcanValueEnums (ByteVulcanEnum, CharVulcanEnum, IntVulcanEnum, LongVulcanEnum, and ShortVulcanEnum), the encoding relies on the encoding of the enumeration's value type (Byte, Char, Int, Long, and Short).

import enumeratum.values.{IntEnum, IntEnumEntry, IntVulcanEnum}

sealed abstract class Day(val value: Int) extends IntEnumEntry

object Day extends IntEnum[Day] with IntVulcanEnum[Day] {
  case object Monday extends Day(1)
  case object Tuesday extends Day(2)
  case object Wednesday extends Day(3)
  case object Thursday extends Day(4)
  case object Friday extends Day(5)
  case object Saturday extends Day(6)
  case object Sunday extends Day(7)

  val values = findValues
}

Codec[Day]
// res3: Codec.Aux[Int, Day] = ImapErrors(
//   codec = Codec("int"),
//   f = enumeratum.values.Vulcan$$$Lambda/0x00007f9f06070bf0@9ab68ce,
//   g = vulcan.Codec$$Lambda/0x00007f9f05f357a0@9ef264
// )