Skip to content

Commit

Permalink
[coroutines] Allow ignoring specified Effect types in `MobiusEffectRo…
Browse files Browse the repository at this point in the history
…uter`
  • Loading branch information
DrewCarlson committed Feb 15, 2023
1 parent a5cfa7b commit 1479747
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
5 changes: 3 additions & 2 deletions mobiuskt-coroutines/api/mobiuskt-coroutines.api
Expand Up @@ -34,7 +34,7 @@ public final class kt/mobius/flow/FlowTransformerKt {
}

public final class kt/mobius/flow/SubtypeEffectHandlerBuilder {
public fun <init> ()V
public fun <init> (Ljava/util/List;)V
public final fun addAction (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
public final fun addConsumer (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function2;)V
public final fun addFunction (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function2;)V
Expand All @@ -43,7 +43,8 @@ public final class kt/mobius/flow/SubtypeEffectHandlerBuilder {
}

public final class kt/mobius/flow/SubtypeEffectHandlerKt {
public static final fun subtypeEffectHandler (Lkotlin/jvm/functions/Function1;)Lkt/mobius/flow/FlowTransformer;
public static final fun subtypeEffectHandler (Ljava/util/List;Lkotlin/jvm/functions/Function1;)Lkt/mobius/flow/FlowTransformer;
public static synthetic fun subtypeEffectHandler$default (Ljava/util/List;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkt/mobius/flow/FlowTransformer;
}

public final class kt/mobius/flow/SubtypeEffectHandlerKt$sam$i$kt_mobius_flow_FlowTransformer$0 : kotlin/jvm/internal/FunctionAdapter, kt/mobius/flow/FlowTransformer {
Expand Down
12 changes: 7 additions & 5 deletions mobiuskt-coroutines/src/commonMain/kotlin/MobiusEffectRouter.kt
Expand Up @@ -5,17 +5,19 @@ import kotlin.reflect.KClass

internal class MobiusEffectRouter<F : Any, E>(
private val effectClasses: Set<KClass<*>>,
private val effectPerformers: List<FlowTransformer<F, E>>
private val effectPerformers: List<FlowTransformer<F, E>>,
private val ignoredEffects: List<KClass<*>>
) : FlowTransformer<F, E> {

private val unhandledEffectHandler =
flowTransformer<F, E> { effects: Flow<F> ->
effects
.filter { effect ->
effectClasses
.none { effectClass ->
effectClass.isInstance(effect)
}
ignoredEffects.none { effectClass ->
effectClass.isInstance(effect)
} && effectClasses.none { effectClass ->
effectClass.isInstance(effect)
}
}
.map { effect -> throw UnknownEffectException(effect) }
}
Expand Down
Expand Up @@ -9,14 +9,17 @@ import kotlin.reflect.KClass
import kotlin.reflect.cast

public fun <F : Any, E> subtypeEffectHandler(
ignoredEffects: List<KClass<*>> = emptyList(),
block: SubtypeEffectHandlerBuilder<F, E>.() -> Unit
): FlowTransformer<F, E> =
SubtypeEffectHandlerBuilder<F, E>()
SubtypeEffectHandlerBuilder<F, E>(ignoredEffects)
.apply(block)
.build()

@Suppress("RemoveExplicitTypeArguments")
public class SubtypeEffectHandlerBuilder<F : Any, E> {
public class SubtypeEffectHandlerBuilder<F : Any, E>(
private val ignoredEffects: List<KClass<*>>
) {
private val effectPerformerMap = hashMapOf<KClass<*>, FlowTransformer<F, E>>()

public inline fun <reified G : F> addTransformer(
Expand Down Expand Up @@ -97,6 +100,7 @@ public class SubtypeEffectHandlerBuilder<F : Any, E> {
public fun build(): FlowTransformer<F, E> =
MobiusEffectRouter(
effectClasses = effectPerformerMap.keys.toImmutableSet(),
effectPerformers = effectPerformerMap.values.toImmutableList()
effectPerformers = effectPerformerMap.values.toImmutableList(),
ignoredEffects = ignoredEffects.toImmutableList()
)
}
Expand Up @@ -14,9 +14,11 @@ class FlowSubtypeEffectHandlerTest {
private lateinit var action: RecordingConsumer<Effect.Test4>
private lateinit var handler: FlowTransformer<Effect, Event>

private interface IEffect

private sealed class Effect {
data class Test1(val value: Int) : Effect()
data class Test2(val value: Int) : Effect()
data class Test2(val value: Int) : Effect(), IEffect
data class Test3(val value: Int) : Effect()
object Test4 : Effect()

Expand Down Expand Up @@ -86,4 +88,16 @@ class FlowSubtypeEffectHandlerTest {
}
}
}

@Test
fun testIgnoredEffectsDontThrow() = runTest {
handler = subtypeEffectHandler(
ignoredEffects = listOf(IEffect::class)
) {
addConsumer<Effect.Test1> { }
}
handler(flowOf(Effect.Test2(1))).test {
awaitComplete()
}
}
}

0 comments on commit 1479747

Please sign in to comment.