@@ -49,16 +49,43 @@ object ULongSerializer : StdSerializer<ULong>(ULong::class.java) {
49
49
private fun Class <* >.getStaticJsonValueGetter (): Method ? = this .declaredMethods
50
50
.find { method -> Modifier .isStatic(method.modifiers) && method.annotations.any { it is JsonValue } }
51
51
52
- object ValueClassUnboxSerializer : StdSerializer<Any>(Any : :class.java) {
53
- override fun serialize (value : Any , gen : JsonGenerator , provider : SerializerProvider ) {
54
- val unboxed = value::class .java.getMethod(" unbox-impl" ).invoke(value)
52
+ internal sealed class ValueClassSerializer <T : Any >(t : Class <T >) : StdSerializer<T>(t) {
53
+ object Unbox : ValueClassSerializer<Any>(Any : :class.java) {
54
+ override fun serialize (value : Any , gen : JsonGenerator , provider : SerializerProvider ) {
55
+ val unboxed = value::class .java.getMethod(" unbox-impl" ).invoke(value)
55
56
56
- if (unboxed == null ) {
57
- provider.findNullValueSerializer(null ).serialize(unboxed, gen, provider)
58
- return
57
+ if (unboxed == null ) {
58
+ provider.findNullValueSerializer(null ).serialize(unboxed, gen, provider)
59
+ return
60
+ }
61
+
62
+ provider.findValueSerializer(unboxed::class .java).serialize(unboxed, gen, provider)
63
+ }
64
+ }
65
+
66
+ class StaticJsonValue <T : Any >(
67
+ t : Class <T >, private val staticJsonValueGetter : Method
68
+ ) : ValueClassSerializer<T>(t) {
69
+ private val unboxMethod: Method = t.getMethod(" unbox-impl" )
70
+
71
+ override fun serialize (value : T , gen : JsonGenerator , provider : SerializerProvider ) {
72
+ val unboxed = unboxMethod.invoke(value)
73
+ // As shown in the processing of the factory function, jsonValueGetter is always a static method.
74
+ val jsonValue: Any? = staticJsonValueGetter.invoke(null , unboxed)
75
+ jsonValue
76
+ ?.let { provider.findValueSerializer(it::class .java).serialize(it, gen, provider) }
77
+ ? : provider.findNullValueSerializer(null ).serialize(null , gen, provider)
59
78
}
79
+ }
60
80
61
- provider.findValueSerializer(unboxed::class .java).serialize(unboxed, gen, provider)
81
+ companion object {
82
+ // `t` must be UnboxableValueClass.
83
+ // If create a function with a JsonValue in the value class,
84
+ // it will be compiled as a static method (= cannot be processed properly by Jackson),
85
+ // so use a ValueClassSerializer.StaticJsonValue to handle this.
86
+ fun from (t : Class <* >): ValueClassSerializer <* > = t.getStaticJsonValueGetter()
87
+ ?.let { StaticJsonValue (t, it) }
88
+ ? : Unbox
62
89
}
63
90
}
64
91
@@ -74,7 +101,7 @@ internal class KotlinSerializers : Serializers.Base() {
74
101
UInt ::class .java.isAssignableFrom(type.rawClass) -> UIntSerializer
75
102
ULong ::class .java.isAssignableFrom(type.rawClass) -> ULongSerializer
76
103
// The priority of Unboxing needs to be lowered so as not to break the serialization of Unsigned Integers.
77
- type.rawClass.isUnboxableValueClass() -> ValueClassUnboxSerializer
104
+ type.rawClass.isUnboxableValueClass() -> ValueClassSerializer .from(type.rawClass)
78
105
else -> null
79
106
}
80
107
}
0 commit comments