It took me longer (and more help from chatgpt) than I'd like to figure out a clean way (IMO) of handling unsealed traits and other polymorphic types.
I eventually hit upon this:
import upickle.default.{macroRW, read, write, ReadWriter as RW, readwriter}
trait IntOrBool
case class IntWrapper(i: Int) extends IntOrBool
case class BoolWrapper(b: Boolean) extends IntOrBool
given RW[IntWrapper] = macroRW[IntWrapper]
given RW[BoolWrapper] = macroRW[BoolWrapper]
given RW[IntOrBool] = readwriter[ujson.Value].bimap[IntOrBool](
{
case iw: IntWrapper => writeJs(iw).obj += ("type" -> writeJs("IntWrapper"))
case bw: BoolWrapper => writeJs(bw).obj += ("type" -> writeJs("BoolWrapper"))
case t => throw new IllegalArgumentException(s"Unknown type: $t")
},
json =>
json("type").str match {
case "IntWrapper" => read[IntWrapper](json)
case "BoolWrapper" => read[BoolWrapper](json)
case t => throw new IllegalArgumentException(s"Unknown type: $t")
},
)
Is there a cleaner way? How would you feel about documenting this or some other approach in the reade?
It took me longer (and more help from chatgpt) than I'd like to figure out a clean way (IMO) of handling unsealed traits and other polymorphic types.
I eventually hit upon this:
Is there a cleaner way? How would you feel about documenting this or some other approach in the reade?