In my model I have a subset of Enum Values (using refined types). So I need to provide Decoders for these Enum Values.
I have now the following version that works (I simplified the example with only one enum value):
import io.circe.*
inline def deriveEnumValueDecoder[A](inline prototype: A): Decoder[A] =
Decoder.decodeString.emap: str =>
if str == prototype.toString
then Right(prototype)
else Left(s"Invalid value: $str")
val json = Json.obj("processStatus" -> Json.fromString("OK"))
val jsonEnum = Json.fromString("OK")
println("MyClass: " + json.as[MyClass])
println("MyEnum: " + jsonEnum.as[MyEnum.OK.type])
case class MyClass(processStatus: MyEnum.OK.type)
enum MyEnum:
case OK, NOK
given Decoder[MyClass] = Decoder.derived
given Decoder[MyEnum.OK.type] = deriveEnumValueDecoder(MyEnum.OK)
See Scastie: https://scastie.scala-lang.org/pme123/ntclYMfzQK2U6KP1wv9fIw/2
I was wondering if there is a way to get rid of providing a 'prototype', so I can call it like:
given Decoder[MyEnum.OK.type] = deriveEnumValueDecoder
With the comment of Mateusz Kubuszok:
inline def deriveEnumValueDecoder[A]: Decoder[A] =
Decoder.decodeString.emap: str =>
if str == valueOf[A].toString
then Right(valueOf[A])
else Left(s"Invalid value: $str - expected: ${valueOf[A]}")
given Decoder[MyEnum.OK.type] = deriveEnumValueDecoder