Skip to content

Commit 3e1d457

Browse files
authored
Improve error message for merging non-caseclass readwriters (#602)
Fixes #394 Added a unit test to cover new failure message
1 parent bd2ee89 commit 3e1d457

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

upickle/core/src/upickle/core/Types.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ trait Types{ types =>
3232
extends Visitor.Delegate[Any, T](other) with ReadWriter[T]
3333

3434
def merge[T](tagKey: String, rws: ReadWriter[_ <: T]*): TaggedReadWriter[T] = {
35+
assert(
36+
rws.forall(_.isInstanceOf[TaggedReadWriter[_]]),
37+
"Can only merge ReadWriters of case classes, not " + rws.filterNot(_.isInstanceOf[TaggedReadWriter[_]])
38+
)
3539
new TaggedReadWriter.Node(tagKey, rws.asInstanceOf[Seq[TaggedReadWriter[T]]]:_*)
3640
}
3741

@@ -108,6 +112,10 @@ trait Types{ types =>
108112
override def visitArray(length: Int, index: Int) = super.visitArray(length, index).asInstanceOf[ArrVisitor[Any, Z]]
109113
}
110114
def merge[T](tagKey: String, readers0: Reader[_ <: T]*): TaggedReader.Node[T] = {
115+
assert(
116+
readers0.forall(_.isInstanceOf[TaggedReader[_]]),
117+
"Can only merge Readers of case classes, not " + readers0.filterNot(_.isInstanceOf[TaggedReader[_]])
118+
)
111119
new TaggedReader.Node(tagKey, readers0.asInstanceOf[Seq[TaggedReader[T]]]:_*)
112120
}
113121

@@ -147,6 +155,10 @@ trait Types{ types =>
147155
def write0[R](out: Visitor[_, R], v: U): R = src.write(out, f(v))
148156
}
149157
def merge[T](writers: Writer[_ <: T]*) = {
158+
assert(
159+
writers.forall(_.isInstanceOf[TaggedWriter[_]]),
160+
"Can only merge Writers of case classes, not " + writers.filterNot(_.isInstanceOf[TaggedWriter[_]])
161+
)
150162
new TaggedWriter.Node(writers.asInstanceOf[Seq[TaggedWriter[T]]]:_*)
151163
}
152164
}

upickle/test/src/upickle/FailureTests.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ object WrongTag {
3737

3838
}
3939

40+
object TaggedCustomSerializer{
41+
42+
sealed trait BooleanOrInt
43+
44+
object BooleanOrInt {
45+
implicit val rw: upickle.default.ReadWriter[BooleanOrInt] = upickle.default.macroRW
46+
}
47+
48+
case class IsBoolean(val value: Boolean) extends BooleanOrInt
49+
50+
object IsBoolean {
51+
implicit val rw: upickle.default.ReadWriter[IsBoolean] = upickle.default.readwriter[Boolean].bimap[IsBoolean](_.value, IsBoolean(_))
52+
}
53+
54+
case class IsInt(val value: Int) extends BooleanOrInt
55+
56+
object IsInt {
57+
implicit val rw: upickle.default.ReadWriter[IsInt] = upickle.default.readwriter[Int].bimap[IsInt](_.value, IsInt(_))
58+
}
59+
}
4060
/**
4161
* Generally, every failure should be a Invalid.Json or a
4262
* InvalidData. If any assertion errors, match errors, number
@@ -273,5 +293,15 @@ object FailureTests extends TestSuite {
273293
// upickle.default.read[Int]("10e-1") ==> 1
274294
// upickle.default.read[Long]("10e-1") ==> 1
275295
}
296+
test("taggedCustomSerializer"){
297+
import upickle.default._
298+
299+
val error = intercept[java.lang.AssertionError] {
300+
val x: TaggedCustomSerializer.BooleanOrInt = TaggedCustomSerializer.IsBoolean(false);
301+
upickle.default.write(x)
302+
}
303+
304+
assert(error.getMessage.startsWith("assertion failed: Can only merge Readers of case classes"))
305+
}
276306
}
277307
}

0 commit comments

Comments
 (0)