Skip to content

support deserializing Scala Iterators #639

Description

@pjfanning

This is open just for discussion. jackson-module-scala can serialize Iterators but will fail if you try to deserialize them.

Noone has complained yet.

Most users would use standard collections when it comes to supporting Array-like data types.

Example test:

package com.fasterxml.jackson.module.scala.deser

import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospectorModule
import org.scalatest.BeforeAndAfterEach

object IteratorWithNumberDeserializerTest {
  case class IteratorLong(longs: Iterator[Long])
  case class IteratorJavaLong(longs: Iterator[java.lang.Long])
  case class IteratorBigInt(longs: Iterator[BigInt])
}

class IteratorWithNumberDeserializerTest extends DeserializerTest with BeforeAndAfterEach {
  lazy val module: DefaultScalaModule.type = DefaultScalaModule
  import IteratorWithNumberDeserializerTest._

  private def sumIteratorLong(v: Iterator[Long]): Long = v.sum
  private def sumIteratorJavaLong(v: Iterator[java.lang.Long]): Long = v.map(_.toLong).sum
  private def sumIteratorBigInt(v: Iterator[BigInt]): Long = v.sum.toLong

  "JacksonModuleScala" should "deserialize IteratorLong" in {
    ScalaAnnotationIntrospectorModule.registerReferencedValueType(classOf[IteratorLong], "longs", classOf[Long])
    try {
      val v1 = deserialize("""{"longs":[151,152,153]}""", classOf[IteratorLong])
      v1 shouldBe IteratorLong(Iterator(151L, 152L, 153L))
      //this will next call will fail with a Scala unboxing exception unless you ScalaAnnotationIntrospectorModule.registerReferencedValueType
      //or use one of the equivalent classes in SeqWithNumberDeserializerTest
      sumIteratorLong(v1.longs) shouldBe 456L
    } finally {
      ScalaAnnotationIntrospectorModule.clearRegisteredReferencedTypes()
    }
  }

  it should "deserialize IteratorJavaLong" in {
    val v1 = deserialize("""{"longs":[151,152,153]}""", classOf[IteratorJavaLong])
    v1 shouldBe IteratorJavaLong(Iterator(151L, 152L, 153L))
    sumIteratorJavaLong(v1.longs) shouldBe 456L
  }

  it should "deserialize IteratorBigInt" in {
    val v1 = deserialize("""{"longs":[151,152,153]}""", classOf[IteratorBigInt])
    v1 shouldBe IteratorBigInt(Iterator(151L, 152L, 153L))
    sumIteratorBigInt(v1.longs) shouldBe 456L
  }
}

Exception looks like:

Cannot find a Value deserializer for abstract type [collection-like type; class scala.collection.Iterator, contains [simple type, class long]]
 at [Source: (String)"{"longs":[151,152,153]}"; line: 1, column: 1]
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a Value deserializer for abstract type [collection-like type; class scala.collection.Iterator, contains [simple type, class long]]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions