-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow converting async block to Traits #2411
base: main
Are you sure you want to change the base?
Changes from all commits
7e7a63e
fa53bf6
1802c93
4b4605d
791539e
e74cc89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// | ||
// Driver+Concurrency.swift | ||
// RxCocoa | ||
// | ||
// Created by Jinwoo Kim on 3/30/22. | ||
// Copyright © 2022 Krunoslav Zaher. All rights reserved. | ||
// | ||
|
||
import RxSwift | ||
|
||
#if swift(>=5.5.2) && canImport(_Concurrency) && !os(Linux) | ||
// MARK: - Driver | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
public extension Driver { | ||
/** | ||
Allows converting asynchronous block to `Driver` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- onErrorJustReturn: Element to return in case of error and after that complete the sequence. | ||
- block: An asynchronous block. | ||
- Returns: An Driver emits value from `block` parameter. | ||
*/ | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async throws -> Element, onErrorJustReturn: Element) -> Driver<Element> { | ||
return Single.from(priority: priority, detached: detached, block) | ||
.asDriver(onErrorJustReturn: onErrorJustReturn) | ||
} | ||
|
||
/** | ||
Allows converting asynchronous block to `Driver` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- onErrorDriveWith: Driver that continues to drive the sequence in case of error. | ||
- block: An asynchronous block. | ||
- Returns: An Driver emits value from `block` parameter. | ||
*/ | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async throws -> Element, onErrorDriveWith: Driver<Element>) -> Driver<Element> { | ||
return Single.from(priority: priority, detached: detached, block) | ||
.asDriver(onErrorDriveWith: onErrorDriveWith) | ||
} | ||
|
||
/** | ||
Allows converting asynchronous block to `Driver` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- onErrorRecover: Calculates driver that continues to drive the sequence in case of error. | ||
- block: An asynchronous block. | ||
- Returns: An Driver emits value from `block` parameter. | ||
*/ | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async throws -> Element, onErrorRecover: @escaping (Error) -> Driver<Element>) ->Driver<Element> { | ||
return Single.from(priority: priority, detached: detached, block) | ||
.asDriver(onErrorRecover: onErrorRecover) | ||
} | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// | ||
// Signal+Concurrency.swift | ||
// RxCocoa | ||
// | ||
// Created by Jinwoo Kim on 3/30/22. | ||
// Copyright © 2022 Krunoslav Zaher. All rights reserved. | ||
// | ||
|
||
import RxSwift | ||
|
||
#if swift(>=5.5.2) && canImport(_Concurrency) && !os(Linux) | ||
// MARK: - Signal | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
public extension Signal { | ||
/** | ||
Allows converting asynchronous block to `Signal` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- onErrorJustReturn: Element to return in case of error and after that complete the sequence. | ||
- block: An asynchronous block. | ||
- Returns: An Signal emits value from `block` parameter. | ||
*/ | ||
static func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async throws -> Element, onErrorJustReturn: Element) -> Signal<Element> { | ||
return Single.from(priority: priority, detached: detached, block) | ||
.asSignal(onErrorJustReturn: onErrorJustReturn) | ||
} | ||
|
||
/** | ||
Allows converting asynchronous block to `Signal` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- onErrorSignalWith: Signal that continues to emit the sequence in case of error. | ||
- block: An asynchronous block. | ||
- Returns: An Signal emits value from `block` parameter. | ||
*/ | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
static func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async throws -> Element, onErrorSignalWith: Signal<Element>) -> Signal<Element> { | ||
return Single.from(priority: priority, detached: detached, block) | ||
.asSignal(onErrorSignalWith: onErrorSignalWith) | ||
} | ||
|
||
/** | ||
Allows converting asynchronous block to `Signal` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- onErrorRecover: Calculates signal that continues to emit the sequence in case of error. | ||
- block: An asynchronous block. | ||
- Returns: An Signal emits value from `block` parameter. | ||
*/ | ||
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) | ||
static func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async throws -> Element, onErrorRecover: @escaping (_ error: Swift.Error) -> Signal<Element>) -> Signal<Element> { | ||
return Single.from(priority: priority, detached: detached, block) | ||
.asSignal(onErrorRecover: onErrorRecover) | ||
} | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,11 +27,41 @@ public extension InfallibleType { | |
onCompleted: { continuation.finish() }, | ||
onDisposed: { continuation.onTermination?(.cancelled) } | ||
) | ||
|
||
continuation.onTermination = { @Sendable _ in | ||
disposable.dispose() | ||
} | ||
} | ||
} | ||
|
||
/** | ||
Allows converting asynchronous block to `Infailable` trait. | ||
|
||
- Parameters: | ||
- priority: The priority of the task. | ||
- detached: Detach when creating the task. | ||
- block: An asynchronous block. | ||
- Returns: An Infailable emits value from `block` parameter. | ||
*/ | ||
static func from(priority: TaskPriority? = nil, detached: Bool = false, _ block: @escaping () async -> Element) -> Infallible<Element> { | ||
return .create { observer in | ||
let operation: @Sendable () async -> Void = { | ||
let element = await block() | ||
observer(.next(element)) | ||
observer(.completed) | ||
} | ||
let task: Task<Void, Swift.Error> | ||
|
||
if detached { | ||
task = Task.detached(priority: priority, operation: operation) | ||
} else { | ||
task = Task(priority: priority, operation: operation) | ||
} | ||
|
||
return Disposables.create { | ||
task.cancel() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I left that note to show my train of thought, but now I am thinking it is best to leave this as is and not check I was thinking there should also be a way to indicate they want to return nothing when their Task gets cancelled, but I think the catch block (in the other three, not Infallible) is probably sufficient for that. If they end user cares to know their Single/Maybe/Completable threw an error because the Task was cancelled and not some other error they can check the error type. From the documentation: |
||
} | ||
} | ||
} | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since operation isn't throwing this can be
Task<Void, Never>
. (true for all four locations)