scala - upickle gives a ScalaReflectionException when writing a case class -
i have simple case class:
object margin { def apply(top: int, right: int, bottom: int, left: int): margin = { margin(some(top), some(right), some(bottom), some(left)) } } case class margin(top: option[int], right: option[int], bottom: option[int], left: option[int])
when calling upickle.write
on instance of above class, following exception:
scala.scalareflectionexception: value apply encapsulates multiple overloaded alternatives , cannot treated method. consider invoking `<offending symbol>.asterm.alternatives` , manually picking required method
what error message mean , how fix it?
the above error message result of margin
class having multiple overloaded apply
methods. first 1 case class constructor, , other in companion object. upickle not know apply
method use , throws exception. known limitation.
one workaround rename apply
method in companion object. write custom pickler.
here clumsy version of custom pickler solved problem:
object margin { def create(top: int, right: int, bottom: int, left: int): margin = { margin(some(top), some(right), some(bottom), some(left)) } implicit val marginwriter = upickle.writer[margin]{ case m => js.obj(fields(m).map(kv => (kv._1, js.num(kv._2))):_*).asinstanceof[js.value] } implicit val marginreader = upickle.reader[margin]{ case obj: js.obj => val map = obj.value.tomap margin(map.get("top").map(_.value.asinstanceof[int]), map.get("right").map(_.value.asinstanceof[int]), map.get("bottom").map(_.value.asinstanceof[int]), map.get("left").map(_.value.asinstanceof[int])) } private def fields(m: margin) = seq(m.top.map(("top", _)), m.right.map(("right", _)), m.bottom.map(("bottom", _)), m.left.map(("left", _))).flatten }
Comments
Post a Comment