Czar
01/13/2020, 1:08 PMabstract class UnsignedRequest {
abstract fun signatureData(): String
fun <T : UnsignedRequest> sign(signer: (String) -> Signature): SignedRequest<T> =
SignedRequest(unsignedRequest = this as T, signature = signer(signatureData()))
}
data class SignedRequest<T : UnsignedRequest>(
@JsonUnwrapped val unsignedRequest: T,
val signature: Signature
}
Is there a way to make sign method type-safe? I really don't like the unchecked cast to the type parameter: this as T.
So far I came up with this, which is at least type safe, but repetitive, as I'm essentially copying the signing logic:
interface UnsignedRequest {
fun signatureData(): String
fun sign(signer: (String) -> Signature): SignedRequest<*>
}
data class SignedRequest<T : UnsignedRequest>(
@JsonUnwrapped val unsignedRequest: T,
val signature: Signature
}
data class ActualUnsignedRequest(/* properties */) {
override fun signatureData(): String = /* some composition of properties */
override fun sign(signer: (String) -> Signature) : SignedRequest<ActualUnsignedRequest> =
SignedRequest(req = this, signature = signatureData().let(signer))
}
UPDATE:
Silly me 😄 Forgot about extension functions' awesomeness!
inline fun <T : UnsignedRequest> T.sign(signer: (String) -> String): SignedRequest<T> =
SignedRequest(req = this, signature = signatureData().let(signer))