Skip to content

Commit

Permalink
adding null support for type adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
lmeadors committed Mar 9, 2022
1 parent d77ae84 commit f2ef7c8
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
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)
}

}

0 comments on commit f2ef7c8

Please sign in to comment.