mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 16:09:21 +08:00
Allow user adapters to convert null to non-null in codegen.
Delegate to installed adapters instead of checking for null.
This commit is contained in:
@@ -69,11 +69,9 @@ internal data class DelegateKey(
|
||||
}
|
||||
val finalArgs = arrayOf(*standardArgs, *args)
|
||||
|
||||
val nullModifier = if (nullable) ".nullSafe()" else ".nonNull()"
|
||||
|
||||
return PropertySpec.builder(adapterName, adapterTypeName, KModifier.PRIVATE)
|
||||
.addAnnotations(jsonQualifiers)
|
||||
.initializer("%1N.adapter%2L(%3L$initializerString)$nullModifier", *finalArgs)
|
||||
.initializer("%1N.adapter%2L(%3L$initializerString)", *finalArgs)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
@@ -413,7 +413,7 @@ class GeneratedAdaptersTest {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
fail()
|
||||
} catch (expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Unexpected null at \$.a")
|
||||
assertThat(expected).hasMessage("Non-null value 'a' was null at \$.a")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +432,10 @@ class GeneratedAdaptersTest {
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class HasNonNullConstructorParameter(val a: String)
|
||||
data class HasNonNullConstructorParameter(val a: String)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class HasNullableConstructorParameter(val a: String?)
|
||||
|
||||
@Test fun explicitNull() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
@@ -592,7 +595,7 @@ class GeneratedAdaptersTest {
|
||||
jsonAdapter.fromJson("{\"a\":null}")
|
||||
fail()
|
||||
} catch (expected: JsonDataException) {
|
||||
assertThat(expected).hasMessage("Unexpected null at \$.a")
|
||||
assertThat(expected).hasMessage("Non-null value 'a' was null at \$.a")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,6 +1086,50 @@ class GeneratedAdaptersTest {
|
||||
assertThat(adapter.fromJson("null")).isNull()
|
||||
assertThat(adapter.toJson(null)).isEqualTo("null")
|
||||
}
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class Nullable
|
||||
|
||||
@Test fun delegatesToInstalledAdaptersBeforeNullChecking() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(object {
|
||||
@FromJson fun fromJson(@Nullable string: String?): String {
|
||||
return string ?: "fallback"
|
||||
}
|
||||
|
||||
@ToJson fun toJson(@Nullable value: String?): String {
|
||||
return value ?: "fallback"
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
||||
val hasNonNullConstructorParameterAdapter =
|
||||
moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||
assertThat(hasNonNullConstructorParameterAdapter
|
||||
.fromJson("{\"a\":null}")).isEqualTo(HasNonNullConstructorParameter("fallback"))
|
||||
|
||||
val hasNullableConstructorParameterAdapter =
|
||||
moshi.adapter(HasNullableConstructorParameter::class.java)
|
||||
assertThat(hasNullableConstructorParameterAdapter
|
||||
.fromJson("{\"a\":null}")).isEqualTo(HasNullableConstructorParameter("fallback"))
|
||||
assertThat(hasNullableConstructorParameterAdapter
|
||||
.toJson(HasNullableConstructorParameter(null))).isEqualTo("{\"a\":\"fallback\"}")
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class HasNullableTypeWithGeneratedAdapter(val a: HasNonNullConstructorParameter?)
|
||||
|
||||
@Test fun delegatesToInstalledAdaptersBeforeNullCheckingWithGeneratedAdapter() {
|
||||
val moshi = Moshi.Builder().build()
|
||||
val adapter = moshi.adapter(HasNullableTypeWithGeneratedAdapter::class.java)
|
||||
|
||||
val encoded = HasNullableTypeWithGeneratedAdapter(null)
|
||||
assertThat(adapter.toJson(encoded)).isEqualTo("""{}""")
|
||||
assertThat(adapter.serializeNulls().toJson(encoded)).isEqualTo("""{"a":null}""")
|
||||
|
||||
val decoded = adapter.fromJson("""{"a":null}""")!!
|
||||
assertThat(decoded.a).isEqualTo(null)
|
||||
}
|
||||
}
|
||||
|
||||
// Has to be outside to avoid Types seeing an owning class
|
||||
|
@@ -170,7 +170,9 @@ class KotlinJsonAdapterTest {
|
||||
}
|
||||
}
|
||||
|
||||
class HasNonNullConstructorParameter(val a: String)
|
||||
data class HasNonNullConstructorParameter(val a: String)
|
||||
|
||||
data class HasNullableConstructorParameter(val a: String?)
|
||||
|
||||
@Test fun nonNullPropertySetToNullFailsWithJsonDataException() {
|
||||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
@@ -853,6 +855,31 @@ class KotlinJsonAdapterTest {
|
||||
assertThat(adapter.toJson(value)).isEqualTo(json)
|
||||
}
|
||||
|
||||
@Retention(RUNTIME)
|
||||
annotation class Nullable
|
||||
|
||||
@Test fun delegatesToInstalledAdaptersBeforeNullChecking() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(object {
|
||||
@FromJson fun fromJson(@Nullable string: String?): String {
|
||||
return string ?: "fallback"
|
||||
}
|
||||
|
||||
@ToJson fun toJson(@Nullable value: String?): String {
|
||||
return value ?: "fallback"
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
||||
assertThat(moshi.adapter(HasNonNullConstructorParameter::class.java)
|
||||
.fromJson("{\"a\":null}")).isEqualTo(HasNonNullConstructorParameter("fallback"))
|
||||
|
||||
assertThat(moshi.adapter(HasNullableConstructorParameter::class.java)
|
||||
.fromJson("{\"a\":null}")).isEqualTo(HasNullableConstructorParameter("fallback"))
|
||||
assertThat(moshi.adapter(HasNullableConstructorParameter::class.java)
|
||||
.toJson(HasNullableConstructorParameter(null))).isEqualTo("{\"a\":\"fallback\"}")
|
||||
}
|
||||
|
||||
@Test fun mixingReflectionAndCodegen() {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
|
Reference in New Issue
Block a user