Skip to content

Instantly share code, notes, and snippets.

@scf37
Last active February 16, 2019 13:05
Show Gist options
  • Save scf37/4207c960a6932c7add9cb7f108a875ee to your computer and use it in GitHub Desktop.
Save scf37/4207c960a6932c7add9cb7f108a875ee to your computer and use it in GitHub Desktop.
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import scala.reflect.runtime.universe._
class ScalaEnumDeserializer[T](implicit tag: TypeTag[T]) extends JsonDeserializer[T] {
private[this] val values: Map[String, T] = {
val knownSubclasses = tag.tpe.typeSymbol.asClass.knownDirectSubclasses.filter(_.isModuleClass)
//sealed trait and have subclasses-objects - an enum!
knownSubclasses.map { e =>
val v = runtimeMirror(getClass.getClassLoader).reflectModule(e.asClass.module.asModule).instance.asInstanceOf[T]
v.toString -> v
}.toMap
}
private[this] val name = tag.tpe.typeSymbol.name.toString.trim
override def deserialize(p: JsonParser, ctxt: DeserializationContext): T = {
val v = p.getText()
values.get(v) match {
case Some(r) => r
case None => throw new RuntimeException(s"Unknown value '${v}' for enum ${name}. Valid values are: " +
values.keys.toList.sorted.map("'" + _ + "'").mkString(", "))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment