diff --git a/src/main/kotlin/dev/silenium/libs/flows/impl/FlowGraphImpl.kt b/src/main/kotlin/dev/silenium/libs/flows/impl/FlowGraphImpl.kt index 236bf11..0a7926d 100644 --- a/src/main/kotlin/dev/silenium/libs/flows/impl/FlowGraphImpl.kt +++ b/src/main/kotlin/dev/silenium/libs/flows/impl/FlowGraphImpl.kt @@ -3,6 +3,9 @@ package dev.silenium.libs.flows.impl import dev.silenium.libs.flows.api.* import kotlinx.coroutines.* import kotlinx.coroutines.flow.map +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext import kotlin.reflect.KClass @@ -147,10 +150,14 @@ internal fun FlowGraph.builder() = FlowGraphConfigScopeImpl(this) * @see FlowGraph * @see CoroutineContext */ +@OptIn(ExperimentalContracts::class) suspend fun FlowGraph( coroutineContext: CoroutineContext = Dispatchers.Default, block: FlowGraphConfigScope.() -> Unit, -): FlowGraph = FlowGraphImpl(coroutineContext).builder().apply(block).configure().getOrThrow() +): FlowGraph { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return FlowGraphImpl(coroutineContext).builder().apply(block).configure().getOrThrow() +} /** * Creates a new [FlowGraph] with the given [coroutineScope] and [block] configuration. @@ -163,7 +170,11 @@ suspend fun FlowGraph( * @see FlowGraph * @see CoroutineScope */ +@OptIn(ExperimentalContracts::class) suspend fun FlowGraph( coroutineScope: CoroutineScope, block: FlowGraphConfigScope.() -> Unit, -): FlowGraph = FlowGraphImpl(coroutineScope).builder().apply(block).configure().getOrThrow() +): FlowGraph { + contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + return FlowGraphImpl(coroutineScope).builder().apply(block).configure().getOrThrow() +} diff --git a/src/test/kotlin/dev/silenium/libs/flows/impl/FlowGraphImplTest.kt b/src/test/kotlin/dev/silenium/libs/flows/impl/FlowGraphImplTest.kt index f981723..02c0621 100644 --- a/src/test/kotlin/dev/silenium/libs/flows/impl/FlowGraphImplTest.kt +++ b/src/test/kotlin/dev/silenium/libs/flows/impl/FlowGraphImplTest.kt @@ -1,5 +1,6 @@ package dev.silenium.libs.flows.impl +import dev.silenium.libs.flows.api.SourceFlowGraphElement import dev.silenium.libs.flows.buffer.BufferSink import dev.silenium.libs.flows.buffer.BufferSource import dev.silenium.libs.flows.test.Base64Buffer @@ -16,8 +17,9 @@ import kotlinx.coroutines.flow.firstOrNull class FlowGraphImplTest : FunSpec({ test("FlowGraphBuilder") { + val source: SourceFlowGraphElement> val graph = FlowGraph(CoroutineScope(Dispatchers.Default)) { - val source = source(BufferSource(0u to DataType.BASE64), "buffer-source") + source = source(BufferSource(0u to DataType.BASE64), "buffer-source") val sink = sink(BufferSink(), "buffer-sink") val decoder = transformer(Base64Decoder(), "base64-decoder") connect(source to decoder) @@ -25,7 +27,6 @@ class FlowGraphImplTest : FunSpec({ sourcePad + 1u } } - val source = graph.source>("buffer-source")!! val sink = graph.sink>("buffer-sink")!! val input = "test"