@@ -16,6 +16,7 @@ import kotlin.reflect.full.isSubtypeOf
16
16
import kotlin.reflect.full.memberProperties
17
17
import kotlin.reflect.full.primaryConstructor
18
18
import kotlin.reflect.full.starProjectedType
19
+ import kotlin.reflect.full.withNullability
19
20
import kotlin.reflect.jvm.jvmErasure
20
21
21
22
fun obj (init : JsonObject .() -> Unit ): JsonObject {
@@ -51,10 +52,16 @@ fun JsonObject.arrayField(key: String, vararg values: Any) {
51
52
fun JsonObject.flexGet (name : String , ignoreCase : Boolean = true, ignoreUnderscores : Boolean = true): JsonElement ? {
52
53
val key = keys.filter { normalize(it, ignoreCase, ignoreUnderscores) == normalize(name, ignoreCase, ignoreUnderscores) }
53
54
.firstOrNull()
54
- if (key != null ) {
55
- return get(key)
55
+ return if (key != null ) {
56
+ val value = get(key)
57
+ if (value?.isNull() == true ) {
58
+ // handle json null as null
59
+ null
60
+ } else {
61
+ value
62
+ }
56
63
} else {
57
- return null
64
+ null
58
65
}
59
66
}
60
67
@@ -73,25 +80,26 @@ fun <T : Any> JsonObject.construct(clazz: KClass<T>): T {
73
80
74
81
primaryConstructor!! .parameters.forEach {
75
82
val name = it.name.orEmpty()
76
- if (it.type.isSubtypeOf(Int ::class .starProjectedType)) {
83
+ val nonNullableType = it.type.withNullability(false )
84
+ if (nonNullableType.isSubtypeOf(Int ::class .starProjectedType)) {
77
85
paramz.put(it, flexGet(name)?.asInt())
78
- } else if (it.type .isSubtypeOf(Long ::class .starProjectedType)) {
86
+ } else if (nonNullableType .isSubtypeOf(Long ::class .starProjectedType)) {
79
87
paramz.put(it, flexGet(name)?.asLong())
80
- } else if (it.type .isSubtypeOf(Float ::class .starProjectedType)) {
88
+ } else if (nonNullableType .isSubtypeOf(Float ::class .starProjectedType)) {
81
89
paramz.put(it, flexGet(name)?.asFloat())
82
- } else if (it.type .isSubtypeOf(Double ::class .starProjectedType)) {
90
+ } else if (nonNullableType .isSubtypeOf(Double ::class .starProjectedType)) {
83
91
paramz.put(it, flexGet(name)?.asDouble())
84
- } else if (it.type .isSubtypeOf(BigInteger ::class .starProjectedType)) {
92
+ } else if (nonNullableType .isSubtypeOf(BigInteger ::class .starProjectedType)) {
85
93
paramz.put(it, flexGet(name)?.asNumber())
86
- } else if (it.type .isSubtypeOf(BigDecimal ::class .starProjectedType)) {
94
+ } else if (nonNullableType .isSubtypeOf(BigDecimal ::class .starProjectedType)) {
87
95
paramz.put(it, flexGet(name)?.asNumber())
88
- } else if (it.type .isSubtypeOf(Long ::class .starProjectedType)) {
96
+ } else if (nonNullableType .isSubtypeOf(Long ::class .starProjectedType)) {
89
97
paramz.put(it, flexGet(name)?.asLong())
90
- } else if (it.type .isSubtypeOf(String ::class .starProjectedType)) {
98
+ } else if (nonNullableType .isSubtypeOf(String ::class .starProjectedType)) {
91
99
paramz.put(it, flexGet(name)?.asString())
92
- } else if (it.type .isSubtypeOf(Boolean ::class .starProjectedType)) {
100
+ } else if (nonNullableType .isSubtypeOf(Boolean ::class .starProjectedType)) {
93
101
paramz.put(it, flexGet(name)?.asBoolean())
94
- } else if (it.type .isSubtypeOf(Enum ::class .starProjectedType)) {
102
+ } else if (nonNullableType .isSubtypeOf(Enum ::class .starProjectedType)) {
95
103
val enumName = flexGet(name)?.asString()
96
104
if (enumName != null ) {
97
105
@Suppress(" UNCHECKED_CAST" ) // we already checked but too hard for Kotlin to figure out
@@ -144,21 +152,24 @@ private fun toUnderscore(propertyName: String): String {
144
152
145
153
private fun jsonElement (returnType : KType , value : Any? ): JsonElement {
146
154
val jsonElement: JsonElement
147
- if (value == null ) return nullValue()
148
- if (returnType.isSubtypeOf(Number ::class .starProjectedType) ||
149
- returnType.isSubtypeOf(String ::class .starProjectedType) ||
150
- returnType.isSubtypeOf(Boolean ::class .starProjectedType)
155
+ if (value == null ) {
156
+ return nullValue()
157
+ }
158
+ val nonNullableReturnType = returnType.withNullability(false )
159
+ if (nonNullableReturnType.isSubtypeOf(Number ::class .starProjectedType) ||
160
+ nonNullableReturnType.isSubtypeOf(String ::class .starProjectedType) ||
161
+ nonNullableReturnType.isSubtypeOf(Boolean ::class .starProjectedType)
151
162
) {
152
163
jsonElement = primitive(value)
153
- } else if (returnType .isSubtypeOf(Collection ::class .starProjectedType)) {
164
+ } else if (nonNullableReturnType .isSubtypeOf(Collection ::class .starProjectedType)) {
154
165
val arr = array()
155
166
Collection ::class .cast(value).forEach {
156
167
if (it != null ) {
157
168
arr.add(jsonElement(it::class .starProjectedType, it))
158
169
}
159
170
}
160
171
jsonElement = arr
161
- } else if (returnType .isSubtypeOf(Map ::class .starProjectedType)) {
172
+ } else if (nonNullableReturnType .isSubtypeOf(Map ::class .starProjectedType)) {
162
173
val newObj = JsonObject ()
163
174
Map ::class .cast(value).forEach {
164
175
if (it.key != null ) {
0 commit comments