I have problem with BSON serialization with ADT structure and Enumeration library.
Example structure:
sealed trait Color {
def value: String
}
case class UnknownColor(value : String) extends Color
sealed abstract class KnownColor(val value: String) extends StringEnumEntry with Color
object KnownColor extends StringEnum[KnownColor]{
override def values: IndexedSeq[KnownColor] = findValues
case object Red extends KnownColor("red")
case object Blue extends KnownColor("blue")
}
case class ColorWrapper(
id: UUID,
color: Color
)
I want to save in DB ColorWrapper. To do this I tried to create handlers like this:
implicit val knownColorFormat = new EnumHandler[KnownColor](KnownColor) //my own handler
implicit val unknownColorFormat = Macros.handler[UnknownColor]
type PredefinedColor = UnionType[KnownColor \/ UnknownColor] with Verbose
implicit val predefinedColor = Macros.handlerOpts[Color, PredefinedColor]
implicit val colorWrapperHandler = Macros.handler[ColorWrapper]
It compiles, but while testing writing ColorWrapper(UUID.randomUUID(), KnownColor.Red) I got runtime error:
reactivemongo.api.bson.exceptions.HandlerException, with message: Fails to handle 'color': Value doesn't match: Red.
From verbose I see that there is no KnownColor:
[info] /..../EnumTraitTest.scala:54:52: // Writer (predefinedColor)
[info] {
[info] val macroCfg$macro$17: _root_.reactivemongo.api.bson.MacroConfiguration = bson.this.MacroConfiguration.default[reactivemongo.api.bson.MacroOptions](MacroOptions.this.ValueOf.optionsDefault);
[info] macroVal match {
[info] case (macroVal$macro$18 @ (_: EnumTraitTest.this.UnknownColor)) => EnumTraitTest.this.unknownColorFormat.writeTry(macroVal$macro$18).map(((x$1) => x$1.$plus$plus(_root_.reactivemongo.api.bson.BSONElement(macroCfg$macro$17.discriminator, _root_.reactivemongo.api.bson.BSONString(macroCfg$macro$17.typeNaming(implicitly[_root_.scala.reflect.ClassTag[EnumTraitTest.this.UnknownColor]].runtimeClass))))))
[info] case _ => _root_.scala.util.Failure(_root_.reactivemongo.api.bson.exceptions.ValueDoesNotMatchException(macroVal.toString))
[info] }
[info] }
[info] implicit val predefinedColor = Macros.handlerOpts[Color, PredefinedColor]
Why
predefinedColor does not contain KnownColor? Is there any other way to create macro to serialize it?