Scala gives the developer the possibility of using Enumerations. If they should be used or if Case Classes are better is a debate I’m not going to start here. They exist and they can be used.
The reason I mention enumerations is that in a personal project (which I hope to publish soon, but I digress) I’ve been using them inside some case classes. In the same project I’m using Play-JSON, a standalone version of the Play Framework JSON libraries, which turn working with JSON into a boilerplate-free pleasure. All was grand until I added my first enumeration as a parameter in a case class. The compiler started to complain and it took me a while to find how to fix it.
The solution was provided by, who else, StackOverflow which in just 5 years has become an invaluable resource. I thought this may be useful to other people, so I created some basic sample code showing the solution to the issue and pushed it to a Github repository. As always, feel free to clone and comment.
Let’s assume we have the following code structure:
We can take advantage of Play-JSON and create a companion object for our case class that will helps us serializing instances of this class from or into JSON.
Unfortunately, when compiling we will get errors due to the enumerations missing valid Reads and Writes. We can test this by removing the enum parameters from the case class and replacing them by simple types as shown below. The code works and converts the case class into JSON, which proves that the issue is the enumeration type that can’t be managed by Play-JSON.
The solution is, obviously, to provide Reads and Writes for the enumerations. But we would like to do it in a generic way, to avoid duplication of very similar code. StackOverflow provides an example of a support class that can accomplish this:
This creates an object that provides generic Reads, Writes and Format methods that can be used with any enumeration. We can use the methods in our enumerations, adding some implicit vals of type Reads and Writes that will redirect the execution flow to the support object, as follows:
By adding this support object and the enumeration-specific vals, we can now compile the project and serialize our case class into JSON.