Coverage Summary for Class: CombinedStateFlow (dev.shreyaspatil.permissionFlow.utils.stateFlow)
Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
CombinedStateFlow |
100%
(4/4)
|
|
100%
(6/6)
|
100%
(43/43)
|
CombinedStateFlow$collect$1 |
|
CombinedStateFlow$collect$2 |
100%
(1/1)
|
|
100%
(2/2)
|
100%
(35/35)
|
Total |
100%
(5/5)
|
|
100%
(8/8)
|
100%
(78/78)
|
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 value
27 * at the instant.
28 */
29 private class CombinedStateFlow<T>(
30 private val getValue: () -> T,
31 private val flow: Flow<T>,
32 ) : StateFlow<T> {
33 override val replayCache: List<T>
34 get() = listOf(value)
35
36 override val value: T
37 get() = getValue()
38
39 override suspend fun collect(collector: FlowCollector<T>): Nothing = coroutineScope {
40 flow.stateIn(this).collect(collector)
41 }
42 }
43
44 /** Returns implementation of [CombinedStateFlow] */
45 internal fun <T> combineStates(
46 getValue: () -> T,
47 flow: Flow<T>,
48 ): StateFlow<T> = CombinedStateFlow(getValue, flow)
49
50 /** Combines multiple [StateFlow]s and transforms them into another [StateFlow] */
51 internal inline fun <reified T, R> combineStates(
52 vararg stateFlows: StateFlow<T>,
53 crossinline transform: (Array<T>) -> R,
54 ): StateFlow<R> =
55 combineStates(
56 getValue = { transform(stateFlows.map { it.value }.toTypedArray()) },
57 flow = combine(*stateFlows) { transform(it) },
58 )