Skip to content

Commit 85a2601

Browse files
Add parametrized Flow#filterIsInstance extension (#3464)
Fixes #3240
1 parent dc58806 commit 85a2601

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

kotlinx-coroutines-core/api/kotlinx-coroutines-core.api

+1
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ public final class kotlinx/coroutines/flow/FlowKt {
973973
public static final fun emitAll (Lkotlinx/coroutines/flow/FlowCollector;Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
974974
public static final fun emptyFlow ()Lkotlinx/coroutines/flow/Flow;
975975
public static final fun filter (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
976+
public static final fun filterIsInstance (Lkotlinx/coroutines/flow/Flow;Lkotlin/reflect/KClass;)Lkotlinx/coroutines/flow/Flow;
976977
public static final fun filterNot (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
977978
public static final fun filterNotNull (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
978979
public static final fun first (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

kotlinx-coroutines-core/common/src/flow/operators/Transform.kt

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ package kotlinx.coroutines.flow
1111
import kotlinx.coroutines.*
1212
import kotlinx.coroutines.flow.internal.*
1313
import kotlin.jvm.*
14+
import kotlin.reflect.*
1415
import kotlinx.coroutines.flow.internal.unsafeFlow as flow
1516
import kotlinx.coroutines.flow.unsafeTransform as transform
1617

@@ -34,6 +35,11 @@ public inline fun <T> Flow<T>.filterNot(crossinline predicate: suspend (T) -> Bo
3435
@Suppress("UNCHECKED_CAST")
3536
public inline fun <reified R> Flow<*>.filterIsInstance(): Flow<R> = filter { it is R } as Flow<R>
3637

38+
/**
39+
* Returns a flow containing only values that are instances of the given [klass].
40+
*/
41+
public fun <R : Any> Flow<*>.filterIsInstance(klass: KClass<R>): Flow<R> = filter { klass.isInstance(it) } as Flow<R>
42+
3743
/**
3844
* Returns a flow containing only values of the original flow that are not null.
3945
*/

kotlinx-coroutines-core/common/test/flow/operators/FilterTrivialTest.kt

+33
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,33 @@ class FilterTrivialTest : TestBase() {
2828
assertEquals("value", flow.filterIsInstance<String>().single())
2929
}
3030

31+
@Test
32+
fun testParametrizedFilterIsInstance() = runTest {
33+
val flow = flowOf("value", 2.0)
34+
assertEquals(2.0, flow.filterIsInstance(Double::class).single())
35+
assertEquals("value", flow.filterIsInstance(String::class).single())
36+
}
37+
38+
@Test
39+
fun testSubtypesFilterIsInstance() = runTest {
40+
open class Super
41+
class Sub : Super()
42+
43+
val flow = flowOf(Super(), Super(), Super(), Sub(), Sub(), Sub())
44+
assertEquals(6, flow.filterIsInstance<Super>().count())
45+
assertEquals(3, flow.filterIsInstance<Sub>().count())
46+
}
47+
48+
@Test
49+
fun testSubtypesParametrizedFilterIsInstance() = runTest {
50+
open class Super
51+
class Sub : Super()
52+
53+
val flow = flowOf(Super(), Super(), Super(), Sub(), Sub(), Sub())
54+
assertEquals(6, flow.filterIsInstance(Super::class).count())
55+
assertEquals(3, flow.filterIsInstance(Sub::class).count())
56+
}
57+
3158
@Test
3259
fun testFilterIsInstanceNullable() = runTest {
3360
val flow = flowOf(1, 2, null)
@@ -40,4 +67,10 @@ class FilterTrivialTest : TestBase() {
4067
val sum = emptyFlow<Int>().filterIsInstance<Int>().sum()
4168
assertEquals(0, sum)
4269
}
70+
71+
@Test
72+
fun testEmptyFlowParametrizedIsInstance() = runTest {
73+
val sum = emptyFlow<Int>().filterIsInstance(Int::class).sum()
74+
assertEquals(0, sum)
75+
}
4376
}

0 commit comments

Comments
 (0)