Coverage Summary for Class: CombinedStateFlow (dev.shreyaspatil.permissionFlow.utils.stateFlow)
Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
CombinedStateFlow |
100%
(4/4)
|
|
100%
(7/7)
|
100%
(39/39)
|
CombinedStateFlow$collect$1 |
|
CombinedStateFlow$collect$2 |
100%
(1/1)
|
|
100%
(1/1)
|
100%
(43/43)
|
Total |
100%
(5/5)
|
|
100%
(8/8)
|
100%
(82/82)
|
1 /**
2 * Copyright 2022 Shreyas Patil
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package dev.shreyaspatil.permissionFlow.utils.stateFlow
17
18 import kotlinx.coroutines.coroutineScope
19 import kotlinx.coroutines.flow.Flow
20 import kotlinx.coroutines.flow.FlowCollector
21 import kotlinx.coroutines.flow.StateFlow
22 import kotlinx.coroutines.flow.combine
23 import kotlinx.coroutines.flow.stateIn
24
25 /**
26 * [StateFlow] which delegates [flow] to use it as StateFlow and uses [getValue] to calculate
27 * value at the instant.
28 */
29 private class CombinedStateFlow<T>(
30 private val getValue: () -> T,
31 private val flow: Flow<T>,
32 ) : StateFlow<T> {
33
34 override val replayCache: List<T> get() = listOf(value)
35
36 override val value: T get() = getValue()
37
38 override suspend fun collect(collector: FlowCollector<T>): Nothing =
39 coroutineScope { flow.stateIn(this).collect(collector) }
40 }
41
42 /**
43 * Returns implementation of [CombinedStateFlow]
44 */
45 internal fun <T> combineStates(
46 getValue: () -> T,
47 flow: Flow<T>,
48 ): StateFlow<T> = CombinedStateFlow(getValue, flow)
49
50 /**
51 * Combines multiple [StateFlow]s and transforms them into another [StateFlow]
52 */
53 internal inline fun <reified T, R> combineStates(
54 vararg stateFlows: StateFlow<T>,
55 crossinline transform: (Array<T>) -> R,
56 ): StateFlow<R> = combineStates(
57 getValue = { transform(stateFlows.map { it.value }.toTypedArray()) },
58 flow = combine(*stateFlows) { transform(it) },
59 )