Skip to content

Commit

Permalink
Merge pull request #675 from k163377/seq-ser
Browse files Browse the repository at this point in the history
Modified to use `Converter` in `Sequence` serialization
  • Loading branch information
k163377 authored May 19, 2023
2 parents d2e9ef1 + 632d4bb commit b91f5c2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
12 changes: 12 additions & 0 deletions src/main/kotlin/com/fasterxml/jackson/module/kotlin/Converters.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
package com.fasterxml.jackson.module.kotlin

import com.fasterxml.jackson.databind.JavaType
import com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer
import com.fasterxml.jackson.databind.type.TypeFactory
import com.fasterxml.jackson.databind.util.StdConverter
import kotlin.reflect.KClass

internal class SequenceToIteratorConverter(private val input: JavaType) : StdConverter<Sequence<*>, Iterator<*>>() {
override fun convert(value: Sequence<*>): Iterator<*> = value.iterator()

override fun getInputType(typeFactory: TypeFactory): JavaType = input
// element-type may not be obtained, so a null check is required
override fun getOutputType(typeFactory: TypeFactory): JavaType = input.containedType(0)
?.let { typeFactory.constructCollectionLikeType(Iterator::class.java, it) }
?: typeFactory.constructType(Iterator::class.java)
}

// S is nullable because value corresponds to a nullable value class
// @see KotlinNamesAnnotationIntrospector.findNullSerializer
internal class ValueClassBoxConverter<S : Any?, D : Any>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,14 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon
return super.findCreatorAnnotation(config, a)
}

// Find a converter to handle the case where the getter returns an unboxed value from the value class.
override fun findSerializationConverter(a: Annotated): Converter<*, *>? = (a as? AnnotatedMethod)?.let { _ ->
cache.findValueClassReturnType(a)?.let { cache.getValueClassBoxConverter(a.rawReturnType, it) }
override fun findSerializationConverter(a: Annotated): Converter<*, *>? = when (a) {
// Find a converter to handle the case where the getter returns an unboxed value from the value class.
is AnnotatedMethod -> cache.findValueClassReturnType(a)
?.let { cache.getValueClassBoxConverter(a.rawReturnType, it) }
is AnnotatedClass -> a
.takeIf { Sequence::class.java.isAssignableFrom(it.rawType) }
?.let { SequenceToIteratorConverter(it.type) }
else -> null
}

// Determine if the unbox result of value class is nullAable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.math.BigInteger

@Deprecated(
message = "This class will be removed in 2.16 or later as it has been replaced by SequenceToIteratorConverter.",
replaceWith = ReplaceWith("com.fasterxml.jackson.module.kotlin.SequenceToIteratorConverter")
)
object SequenceSerializer : StdSerializer<Sequence<*>>(Sequence::class.java) {
override fun serialize(value: Sequence<*>, gen: JsonGenerator, provider: SerializerProvider) {
provider.defaultSerializeValue(value.iterator(), gen)
Expand Down Expand Up @@ -98,7 +102,6 @@ internal class KotlinSerializers : Serializers.Base() {
val rawClass = type.rawClass

return when {
Sequence::class.java.isAssignableFrom(rawClass) -> SequenceSerializer
UByte::class.java.isAssignableFrom(rawClass) -> UByteSerializer
UShort::class.java.isAssignableFrom(rawClass) -> UShortSerializer
UInt::class.java.isAssignableFrom(rawClass) -> UIntSerializer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.fasterxml.jackson.module.kotlin.test

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import org.junit.Test
Expand Down Expand Up @@ -42,4 +46,39 @@ class TestSequenceDeserializer {
val result = objectMapper.writeValueAsString(data)
assertEquals("{\"value\":[]}", result)
}
}

class ContentSer : StdSerializer<String>(String::class.java) {
override fun serialize(value: String, gen: JsonGenerator, provider: SerializerProvider) {
provider.defaultSerializeValue("$value-ser", gen)
}
}

data class ListWrapper(
@JsonSerialize(contentUsing = ContentSer::class) val value: List<String>
)

data class SequenceWrapper(
@JsonSerialize(contentUsing = ContentSer::class)
val value: Sequence<String>
)

@Test
fun contentUsingTest() {
val mapper = jacksonObjectMapper()

val listResult = mapper.writeValueAsString(ListWrapper(listOf("foo")))
val sequenceResult = mapper.writeValueAsString(SequenceWrapper(sequenceOf("foo")))

assertEquals("""{"value":["foo-ser"]}""", sequenceResult)
assertEquals(listResult, sequenceResult)
}

// @see #674
@Test
fun sequenceOfTest() {
val mapper = jacksonObjectMapper()
val result = mapper.writeValueAsString(sequenceOf("foo"))

assertEquals("""["foo"]""", result)
}
}

0 comments on commit b91f5c2

Please sign in to comment.