Search code examples
javascalajson4s

Convert java enum to scala Enumeration for json4s serialization


I'm using the json4s library to convert scala case classes into json messages. My case classes are dependent on third party java enum types:

//third party java code
public enum Fruit {
    Banana (1),
    Cherry (2);
}

My scala classes then use this enum as a parameter:

case class Order(fruit : Fruit, quantity : Int)

I'm trying to use EnumNameSerializer provided by the `org.json4s.ext' library:

import org.json4s._
import org.json4s.native.Serialization
import org.json4s.native.Serialization.{write, read}
import org.json4s.ext.EnumNameSerializer

case class Order(fruit : Fruit, quantity : Int) {
  implicit lazy val formats =
    DefaultFormats + new EnumNameSerializer(fruit)
}

But, I'm getting a compile time error:

error: inferred type arguments [Fruit] do not conform to class EnumNameSerializer's type parameter bounds [E <: Enumeration]

How do I convert a java enum into a scala Enumeration for json4s' EnumNameSerializer?

I'm hoping to avoid writing a custom serializer since my actual use case involves many different java enum types used in my case class and therefore I would have to write many different custom serializers.

Thank you in advance for your consideration and response.


Solution

  • Would something like this work for you?

    class EnumSerializer[E <: Enum[E]](implicit ct: Manifest[E]) extends CustomSerializer[E](format ⇒ ({
      case JString(name) ⇒ Enum.valueOf(ct.runtimeClass.asInstanceOf[Class[E]], name)
    }, {
      case dt: E ⇒ JString(dt.name())
    }))
    
    
    
    // first enum I could find
    case class X(a: String, enum: java.time.format.FormatStyle)
    implicit val formats = DefaultFormats + new EnumSerializer[java.time.format.FormatStyle]()
    
    // {"a":"test","enum":"FULL"}
    val jsonString = Serialization.write(X("test", FormatStyle.FULL))
    Serialization.read[X](jsonString)