41 lines
1.4 KiB
Kotlin
41 lines
1.4 KiB
Kotlin
package net.sergeych.kiloparsec
|
|
|
|
import kotlinx.serialization.KSerializer
|
|
import kotlinx.serialization.Serializable
|
|
import net.sergeych.bintools.toDataSource
|
|
import net.sergeych.bipack.BipackDecoder
|
|
import net.sergeych.bipack.BipackEncoder
|
|
import net.sergeych.utools.unpack
|
|
|
|
/**
|
|
* Typesafe command definition. Command is a universal entity in Divan: it is used
|
|
* in node-2-node protocols and client API, and most importantly in calling smart contract
|
|
* methods. This is essentially a Kotlin binding to typesafe serialize command calls and
|
|
* deserialize results.
|
|
*/
|
|
class Command<A, R>(
|
|
val name: String,
|
|
val argsSerializer: KSerializer<A>,
|
|
val resultSerializer: KSerializer<R>
|
|
) {
|
|
@Serializable
|
|
data class Call(val name: String,val serializedArgs: UByteArray)
|
|
|
|
fun packCall(args: A): UByteArray = BipackEncoder.encode(
|
|
Call(name, BipackEncoder.encode(argsSerializer, args).toUByteArray())
|
|
).toUByteArray()
|
|
|
|
fun unpackResult(packedResult: UByteArray): R =
|
|
unpack(resultSerializer, packedResult)
|
|
|
|
suspend fun exec(packedArgs: UByteArray, handler: suspend (A) -> R): UByteArray =
|
|
BipackEncoder.encode(
|
|
resultSerializer,
|
|
handler(
|
|
BipackDecoder.decode(packedArgs.toDataSource(), argsSerializer))
|
|
).toUByteArray()
|
|
|
|
companion object {
|
|
fun unpackCall(packedCall: UByteArray): Call = BipackDecoder.decode(packedCall.toDataSource())
|
|
}
|
|
} |