I have an Enumeration created with enumeratum:
sealed trait Language extends EnumEntry
object Language
extends Enum[Language]
with PlayInsensitiveJsonEnum[Language] {
val values: IndexedSeq[Language] = findValues
case object DE extends Language
...
}
If I use it in a Map it throws:
No instance of play.api.libs.json.Format is available for scala.collection.immutable.Map[finnova.bpf.api.entity.Language, java.lang.String] in the implicit scope (Hint: if declared in the same file, make sure it's declared before)
Here is the definition:
case class I18nEntry(values: Map[Language, String])
object I18nEntry {
implicit val jsonFormat: Format[I18nEntry] = Json.format[I18nEntry]
}
This here works:
case class I18nEntry(values: Map[String, String], language: Language)
The Play Format
converter for a Map
will only be implicitly provided if your Map
key is a String
, as JSON object keys must be strings. It doesn't realize that Language
is eventually a String
(or, rather, a JsString
). Therefore you'd need to manually write your own Reads
and Writes
converters for Map[Language, String]
, or alternatively map Language
to a String
key such as you have values: Map[String, String]
as you've done above. For what it's worth, the first solution would take roughly this structure:
val langMapReads: Reads[Map[Language, String]] = ???
val langMapWrites: Writes[Map[Language, String]] = ???
implicit val langMapFormat: Format[Map[Language, String]] = Format(langMapReads, langMapWrites)