All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.rsocket.kotlin.RSocketRequestHandler.kt Maven / Gradle / Ivy

/*
 * Copyright 2015-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.rsocket.kotlin

import io.ktor.utils.io.core.*
import io.rsocket.kotlin.payload.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

public class RSocketRequestHandlerBuilder internal constructor() {
    private var metadataPush: (suspend RSocket.(metadata: ByteReadPacket) -> Unit)? = null
    private var fireAndForget: (suspend RSocket.(payload: Payload) -> Unit)? = null
    private var requestResponse: (suspend RSocket.(payload: Payload) -> Payload)? = null
    private var requestStream: (suspend RSocket.(payload: Payload) -> Flow)? = null
    private var requestChannel: (suspend RSocket.(initPayload: Payload, payloads: Flow) -> Flow)? = null

    public fun metadataPush(block: (suspend RSocket.(metadata: ByteReadPacket) -> Unit)) {
        check(metadataPush == null) { "Metadata Push handler already configured" }
        metadataPush = block
    }

    public fun fireAndForget(block: (suspend RSocket.(payload: Payload) -> Unit)) {
        check(fireAndForget == null) { "Fire and Forget handler already configured" }
        fireAndForget = block
    }

    public fun requestResponse(block: (suspend RSocket.(payload: Payload) -> Payload)) {
        check(requestResponse == null) { "Request Response handler already configured" }
        requestResponse = block
    }

    public fun requestStream(block: suspend (RSocket.(payload: Payload) -> Flow)) {
        check(requestStream == null) { "Request Stream handler already configured" }
        requestStream = block
    }

    public fun requestChannel(block: suspend (RSocket.(initPayload: Payload, payloads: Flow) -> Flow)) {
        check(requestChannel == null) { "Request Channel handler already configured" }
        requestChannel = block
    }

    internal fun build(job: Job): RSocket =
        RSocketRequestHandler(job, metadataPush, fireAndForget, requestResponse, requestStream, requestChannel)
}

@Suppress("FunctionName")
public fun RSocketRequestHandler(parentJob: Job? = null, configure: RSocketRequestHandlerBuilder.() -> Unit): RSocket {
    val builder = RSocketRequestHandlerBuilder()
    builder.configure()
    return builder.build(Job(parentJob))
}

private class RSocketRequestHandler(
    override val job: Job,
    private val metadataPush: (suspend RSocket.(metadata: ByteReadPacket) -> Unit)? = null,
    private val fireAndForget: (suspend RSocket.(payload: Payload) -> Unit)? = null,
    private val requestResponse: (suspend RSocket.(payload: Payload) -> Payload)? = null,
    private val requestStream: (suspend RSocket.(payload: Payload) -> Flow)? = null,
    private val requestChannel: (suspend RSocket.(initPayload: Payload, payloads: Flow) -> Flow)? = null,
) : RSocket {
    override suspend fun metadataPush(metadata: ByteReadPacket): Unit =
        metadataPush?.invoke(this, metadata) ?: super.metadataPush(metadata)

    override suspend fun fireAndForget(payload: Payload): Unit =
        fireAndForget?.invoke(this, payload) ?: super.fireAndForget(payload)

    override suspend fun requestResponse(payload: Payload): Payload =
        requestResponse?.invoke(this, payload) ?: super.requestResponse(payload)

    override fun requestStream(payload: Payload): Flow {
        return if (this.requestStream != null) {
            flow { emitAll(requestStream.invoke(this@RSocketRequestHandler, payload)) }
        } else {
            super.requestStream(payload)
        }
    }

    override fun requestChannel(initPayload: Payload, payloads: Flow): Flow {
        return if (this.requestChannel != null) {
            flow { emitAll(requestChannel.invoke(this@RSocketRequestHandler, initPayload, payloads)) }
        } else {
            super.requestChannel(initPayload, payloads)
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy