diff --git a/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala b/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala index 75ab212..23b2916 100644 --- a/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala +++ b/src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala @@ -17,7 +17,13 @@ class EitherDeserializer(config: DeserializationConfig, try { Left(tp.getCodec.readValue[Object](tp, javaType.containedType(0))) } catch { - case _ => Right(tp.getCodec.readValue[Object](tp, javaType.containedType(1))) + case _ => { + // We don't want to reuse the same parser that was used in the + // try-block, as the read there may have used nextToken() and advanced + // us past the point where we expect to be. + val tpRight = new TreeTraversingParser(node, jp.getCodec) + Right(tpRight.getCodec.readValue[Object](tpRight, javaType.containedType(1))) + } } } } diff --git a/src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala b/src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala new file mode 100644 index 0000000..2560504 --- /dev/null +++ b/src/test/scala/com/codahale/jerkson/tests/EitherSupportSpec.scala @@ -0,0 +1,33 @@ +package com.codahale.jerkson.tests + +import com.codahale.jerkson.Json._ +import com.codahale.simplespec.Spec +import com.codahale.jerkson.ParsingException +import org.codehaus.jackson.node.IntNode +import org.junit.Test + +class EitherSupportSpec extends Spec { + class `An Either of two case classes` { + @Test def `is parseable when the Left is used` = { + val e = parse[Either[CaseClassWithArrays, CaseClass]]("""{"one": "a", "two": [ "b", "c" ], "three": [ 0, 1 ]}""") + + e.isLeft.must(be(true)) + + val c = e.left.get + c.one.must(be("a")) + c.two.must(be(Array[String]("b", "c"))) + c.three.must(be(Array[Int](0, 1))) + } + + @Test def `is parseable when the Right is used` = { + val e = parse[Either[CaseClass, CaseClassWithArrays]]("""{"one": "a", "two": [ "b", "c" ], "three": [ 0, 1 ]}""") + + e.isRight.must(be(true)) + + val c = e.right.get + c.one.must(be("a")) + c.two.must(be(Array[String]("b", "c"))) + c.three.must(be(Array[Int](0, 1))) + } + } +}