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

adding null support for type adapters w/ back compatibility #354

Merged
merged 1 commit into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions klaxon/src/main/java/com/beust/klaxon/TypeFor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import kotlin.reflect.KClass

interface TypeAdapter<Output> where Output: Any {
fun classFor(type: Any): KClass<out Output>
fun classForNullable(type: Any?): KClass<out Output>{
return classFor(type as Any)
}
}

@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,8 @@ class JsonObjectConverter(private val klaxon: Klaxon, private val allPaths: Hash
// We have polymorphic information for this field. Retrieve its TypeAdapter,
// instantiate it, and invoke it with the discriminant value.
val discriminantFieldName = Annotations.retrieveJsonFieldName(klaxon, kc, polymorphicInfo.discriminantField)
val discriminant = jsonObject[discriminantFieldName] as Any
polymorphicInfo.adapter.createInstance().classFor(discriminant)
val discriminant = jsonObject[discriminantFieldName]
polymorphicInfo.adapter.createInstance().classForNullable(discriminant)
} else {
null
}
Expand Down
37 changes: 37 additions & 0 deletions klaxon/src/test/kotlin/com/beust/klaxon/TypeAdapterTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,41 @@ class TypeAdapterTest {
assertThat(r[1]).isInstanceOf(Cat::class.java)
}


@TypeFor(field = "type", adapter = VehicleTypeAdapter::class)
open class Vehicle(open val type: String)
data class Car(override val type: String = "car") : Vehicle(type)
data class Truck(override val type: String = "truck") : Vehicle(type)

class VehicleTypeAdapter : TypeAdapter<Vehicle> {

override fun classFor(type: Any): KClass<out Vehicle> {
TODO("Not used - classForNullable replaces this")
}

override fun classForNullable(type: Any?): KClass<out Vehicle> = when (type) {
null -> Car::class
"car" -> Car::class
"truck" -> Truck::class
else -> throw IllegalArgumentException("Unknown type: $type")
}

}

@Test
fun should_default_to_car() {
val json = """
[
{ "type": "car" },
{ "type": "truck" }
{ "no_type": "should default to car..." }
]
"""
val r = Klaxon().parseArray<Vehicle>(json)
println(r)
assertThat(r!![0]).isInstanceOf(Car::class.java)
assertThat(r[1]).isInstanceOf(Truck::class.java)
assertThat(r[2]).isInstanceOf(Car::class.java)
}

}