blob: 114a32e10d006eddcd724b4c1cb63495660cc586 [file] [log] [blame]
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +03001/*
2 * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3 */
4@file:Suppress("unused", "DeprecatedCallableAddReplaceWith", "UNUSED_PARAMETER")
5package kotlinx.coroutines.flow
6
7import kotlin.coroutines.*
8
9/**
10 * These deprecations are added to improve user experience when they will start to
11 * search for their favourite operators and/or patterns that are missing or renamed in Flow.
12 */
13
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +030014/**
15 * `observeOn` has no direct match in [Flow] API because all terminal flow operators are suspending and
16 * thus use the context of the caller.
17 *
18 * For example, the following code:
19 * ```
20 * flowable
21 * .observeOn(Schedulers.io())
22 * .doOnEach { value -> println("Received $value") }
23 * .subscribe()
24 * ```
25 *
26 * has the following Flow equivalent:
27 * ```
28 * withContext(Dispatchers.IO) {
29 * flow.collect { value -> println("Received $value") }
30 * }
31 *
32 * ```
33 * @suppress
34 */
35@Deprecated(message = "Collect flow in the desired context instead", level = DeprecationLevel.ERROR)
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +030036public fun <T> Flow<T>.observeOn(context: CoroutineContext): Flow<T> = error("Should not be called")
37
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +030038/**
39 * `publishOn` has no direct match in [Flow] API because all terminal flow operators are suspending and
40 * thus use the context of the caller.
41 *
42 * For example, the following code:
43 * ```
44 * flux
45 * .publishOn(Schedulers.io())
46 * .doOnEach { value -> println("Received $value") }
47 * .subscribe()
48 * ```
49 *
50 * has the following Flow equivalent:
51 * ```
52 * withContext(Dispatchers.IO) {
53 * flow.collect { value -> println("Received $value") }
54 * }
55 *
56 * ```
57 * @suppress
58 */
59@Deprecated(message = "Collect flow in the desired context instead", level = DeprecationLevel.ERROR)
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +030060public fun <T> Flow<T>.publishOn(context: CoroutineContext): Flow<T> = error("Should not be called")
61
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +030062/**
63 * `subscribeOn` has no direct match in [Flow] API because [Flow] preserves its context and does not leak it.
64 *
65 * For example, the following code:
66 * ```
67 * flowable
68 * .map { value -> println("Doing map in IO"); value }
69 * .subscribeOn(Schedulers.io())
70 * .observeOn(Schedulers.computation())
71 * .doOnEach { value -> println("Processing $value in computation")
72 * .subscribe()
73 * ```
Vsevolod Tolstopyatovf44942a2019-06-02 16:38:10 +030074 * has the following Flow equivalent:
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +030075 * ```
76 * withContext(Dispatchers.Default) {
77 * flow
78 * .map { value -> println("Doing map in IO"); value }
79 * .flowOn(Dispatchers.IO) // Works upstream, doesn't change downstream
80 * .collect { value ->
81 * println("Processing $value in computation")
82 * }
83 * }
84 * ```
Vsevolod Tolstopyatovf44942a2019-06-02 16:38:10 +030085 * Opposed to subscribeOn, it it **possible** to use multiple `flowOn` operators in the one flow
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +030086 * @suppress
87 */
Vsevolod Tolstopyatovf44942a2019-06-02 16:38:10 +030088@Deprecated(message = "Use flowOn instead", level = DeprecationLevel.ERROR)
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +030089public fun <T> Flow<T>.subscribeOn(context: CoroutineContext): Flow<T> = error("Should not be called")
90
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +030091/** @suppress **/
92@Deprecated(message = "Use BroadcastChannel.asFlow()", level = DeprecationLevel.ERROR)
93public fun BehaviourSubject(): Any = error("Should not be called")
94
95/** @suppress **/
96@Deprecated(
97 message = "ReplaySubject is not supported. The closest analogue is buffered broadcast channel",
98 level = DeprecationLevel.ERROR)
99public fun ReplaySubject(): Any = error("Should not be called")
100
101/** @suppress **/
102@Deprecated(message = "PublishSubject is not supported", level = DeprecationLevel.ERROR)
103public fun PublishSubject(): Any = error("Should not be called")
104
105/** @suppress **/
106@Deprecated(
107 level = DeprecationLevel.ERROR,
108 message = "Flow analogue is named onErrorCollect",
109 replaceWith = ReplaceWith("onErrorCollect(fallback)")
110)
111public fun <T> Flow<T>.onErrorResume(fallback: Flow<T>): Flow<T> = error("Should not be called")
112
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +0300113/**
114 * Self-explanatory, the reason of deprecation is "context preservation" property (you can read more in [Flow] documentation)
115 * @suppress
116 **/
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +0300117@Suppress("UNUSED_PARAMETER", "UNUSED", "DeprecatedCallableAddReplaceWith")
118@Deprecated(message = "withContext in flow body is deprecated, use flowOn instead", level = DeprecationLevel.ERROR)
119public fun <T, R> FlowCollector<T>.withContext(context: CoroutineContext, block: suspend () -> R): Unit = error("Should not be called")
120
Vsevolod Tolstopyatovd3cc25f2019-04-09 19:43:11 +0300121/**
122 * `subscribe` is Rx-specific API that has no direct match in flows.
123 * One can use `launch` instead, for example the following:
124 * ```
125 * flowable
126 * .observeOn(Schedulers.io())
127 * .subscribe({ println("Received $it") }, { println("Exception $it happened") }, { println("Flowable is completed successfully") }
128 * ```
129 *
130 * has the following Flow equivalent:
131 * ```
132 * launch(Dispatchers.IO) {
133 * try {
134 * flow.collect { value ->
135 * println("Received $value")
136 * }
137 * println("Flow is completed successfully")
138 * } catch (e: Throwable) {
139 * println("Exception $e happened")
140 * }
141 * }
142 * ```
143 * But most of the time it is better to use terminal operators like [single] instead of [collect].
144 * @suppress
145 */
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +0300146@Deprecated(message = "Use launch + collect instead", level = DeprecationLevel.ERROR)
147public fun <T> Flow<T>.subscribe(): Unit = error("Should not be called")
148
149/** @suppress **/
150@Deprecated(message = "Use launch + collect instead", level = DeprecationLevel.ERROR)
151public fun <T> Flow<T>.subscribe(onEach: (T) -> Unit): Unit = error("Should not be called")
152
153/** @suppress **/
154@Deprecated(message = "Use launch + collect instead", level = DeprecationLevel.ERROR)
155public fun <T> Flow<T>.subscribe(onEach: (T) -> Unit, onError: (Throwable) -> Unit): Unit = error("Should not be called")
156
Vsevolod Tolstopyatov87884882019-04-09 18:36:22 +0300157/**
158 * Note that this replacement is sequential (`concat`) by default.
159 * For concurrent flatMap [flatMapMerge] can be used instead.
160 * @suppress
161 */
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +0300162@Deprecated(
163 level = DeprecationLevel.ERROR,
Vsevolod Tolstopyatov87884882019-04-09 18:36:22 +0300164 message = "Flow analogue is named flatMapConcat",
165 replaceWith = ReplaceWith("flatMapConcat(mapper)")
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +0300166)
Vsevolod Tolstopyatov87884882019-04-09 18:36:22 +0300167public fun <T, R> Flow<T>.flatMap(mapper: suspend (T) -> Flow<R>): Flow<R> = error("Should not be called")
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +0300168
169/** @suppress **/
170@Deprecated(
171 level = DeprecationLevel.ERROR,
Vsevolod Tolstopyatov87884882019-04-09 18:36:22 +0300172 message = "Flow analogue is named flatMapConcat",
173 replaceWith = ReplaceWith("flatMapConcat(mapper)")
Vsevolod Tolstopyatovd57bfa22019-04-04 14:25:13 +0300174)
175public fun <T, R> Flow<T>.concatMap(mapper: (T) -> Flow<R>): Flow<R> = error("Should not be called")
Vsevolod Tolstopyatov87884882019-04-09 18:36:22 +0300176
Vsevolod Tolstopyatov87884882019-04-09 18:36:22 +0300177/**
178 * Note that this replacement is sequential (`concat`) by default.
179 * For concurrent flatMap [flattenMerge] can be used instead.
180 * @suppress
181 */
182@Deprecated(
183 level = DeprecationLevel.ERROR,
184 message = "Flow analogue is named flattenConcat",
185 replaceWith = ReplaceWith("flattenConcat()")
186)
187public fun <T> Flow<Flow<T>>.merge(): Flow<T> = error("Should not be called")
188
189/** @suppress **/
190@Deprecated(
191 level = DeprecationLevel.ERROR,
192 message = "Flow analogue is named flattenConcat",
193 replaceWith = ReplaceWith("flattenConcat()")
194)
195public fun <T> Flow<Flow<T>>.flatten(): Flow<T> = error("Should not be called")
Vsevolod Tolstopyatovd5478b62019-06-06 11:43:31 +0300196
197/**
198 * Kotlin has a built-in generic mechanism for making chained calls.
199 * If you wish to write something like
200 * ```
201 * myFlow.compose(MyFlowExtensions.ignoreErrors()).collect { ... }
202 * ```
203 * you can replace it with
204 *
205 * ```
206 * myFlow.let(MyFlowExtensions.ignoreErrors()).collect { ... }
207 * ```
208 *
209 * @suppress
210 */
211@Deprecated(
212 level = DeprecationLevel.ERROR,
213 message = "Kotlin analogue of compose is 'let'",
214 replaceWith = ReplaceWith("let(transformer)")
215)
216public fun <T, R> Flow<T>.compose(transformer: Flow<T>.() -> Flow<R>): Flow<R> = error("Should not be called")
217
218/**
219 * @suppress
220 */
221@Deprecated(
222 level = DeprecationLevel.ERROR,
223 message = "Kotlin analogue of 'skip' is 'drop'",
224 replaceWith = ReplaceWith("drop(count)")
225)
226public fun <T> Flow<T>.skip(count: Int): Flow<T> = error("Should not be called")
227
228/**
229 * Flow extension to iterate over elements is [collect].
230 * Foreach wasn't introduced deliberately to avoid confusion.
231 * Flow is not a collection, iteration over it may be not idempotent
232 * and can *launch* computations with side-effects.
233 * This behaviour is not reflected in [forEach] name.
234 * @suppress
235 */
236@Deprecated(
237 level = DeprecationLevel.ERROR,
238 message = "Flow analogue of 'forEach' is 'collect'",
239 replaceWith = ReplaceWith("collect(block)")
240)
241public fun <T> Flow<T>.forEach(action: suspend (value: T) -> Unit): Unit = error("Should not be called")
242
243@Deprecated(
244 level = DeprecationLevel.ERROR,
245 message = "Flow has less verbose 'scan' shortcut",
246 replaceWith = ReplaceWith("scan(initial, operation)")
247)
248public fun <T, R> Flow<T>.scanFold(initial: R, @BuilderInference operation: suspend (accumulator: R, value: T) -> R): Flow<R> = error("Should not be called")