Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support deserializing Scala Iterators #639

Open
pjfanning opened this issue May 24, 2023 · 1 comment
Open

support deserializing Scala Iterators #639

pjfanning opened this issue May 24, 2023 · 1 comment

Comments

@pjfanning
Copy link
Member

pjfanning commented May 24, 2023

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]]
@cowtowncoder
Copy link
Member

I think Java-side behavior is similar; Iterator mostly expected to work for serialization.
Although technically one could quite easily support deserialization (into something to obtain iterator from), not much benefit to do before someone has use case.
But good to have this issue so users can comment etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants