Shawn A
04/24/2019, 3:02 PMfun <R : Any> fromAttr(
prop: KProperty1<T, R>,
transformer: (AttributeValue) -> R
) {
transformers.put(constructorParams.getValue(prop.name), transformer)
}
If I don't supply the type argument I am able to pass a prop
with a different R
than transformer
. For instance:
u.fromAttr(Widget::count) { false }
Where Widget::count
is a Long
. I have to use the form u.fromAttr<Long>(Widget::count) { false }
to get a compiler error. I assume this is happening because of type erasure so Kotlin is inferring R
to be Any
?diesieben07
04/24/2019, 3:04 PM(AttributeValue) -> R
can be thought of as Function1<AttributeValue, out R>
. And that is assignable to Function1<AttributeValue, out Any>
, so Any
is inferred.Shawn A
04/24/2019, 3:08 PMu.fromAttr<...>
diesieben07
04/24/2019, 3:08 PMtransformers
map for?Shawn A
04/24/2019, 3:10 PMclass Unmarshaller<T: Any>(private val cls: KClass<T>) {
private val transformers = mutableMapOf<KParameter, (AttributeValue) -> Any>()
private val constructorParams = cls.primaryConstructor!!.parameters
.map { it.name to it }
.toMap()
fun <R : Any> fromAttr(
prop: KProperty1<T, R>,
transformer: (AttributeValue) -> R
) {
transformers.put(constructorParams.getValue(prop.name), transformer)
}
fun invoke(item: Map<String, AttributeValue>): T {
val params = transformers
.mapValues { (k, func) -> func(item.getValue(k.name!!)) }
return cls.primaryConstructor!!.callBy(params)
}
}
@Test
fun `unmarshall an object from a map of name to AttributeValue`() {
val item = mapOf(
"name" to strAttr("foo"),
"count" to longAttr(55)
)
val u = Unmarshaller(Widget::class)
u.fromAttr(Widget::name) { it.s() }
u.fromAttr(Widget::count) { it.n().toLong() }
val widget = u.invoke(item)
}
diesieben07
04/24/2019, 3:16 PMclass WrappedProperty<T, R>(val property: KProperty1<T, R>)
fun <R : Any> fromAttr(prop: WrappedProperty<T, R>, transformer: (AttributeValue) -> R) {
}
out
) of the KProperty
here.Shawn A
04/24/2019, 3:19 PMdiesieben07
04/24/2019, 3:21 PMShawn A
04/24/2019, 3:21 PMdiesieben07
04/24/2019, 3:23 PM@OnlyInputTypes
. But it's internal.