Skip to content
This repository was archived by the owner on Aug 29, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions Sources/Deferred/ExistentialFuture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,11 @@ public struct Future<Value>: FutureProtocol {
private let box: Box<Value>

/// Create a future whose `upon(_:execute:)` methods forward to `base`.
public init<OtherFuture: FutureProtocol>(_ base: OtherFuture)
where OtherFuture.Value == Value {
if let future = base as? Future<Value> {
public init<Wrapped: FutureProtocol>(_ wrapped: Wrapped) where Wrapped.Value == Value {
if let future = wrapped as? Future<Value> {
self.box = future.box
} else {
self.box = ForwardedTo(base: base)
self.box = ForwardedTo(base: wrapped)
}
}

Expand All @@ -128,8 +127,8 @@ public struct Future<Value>: FutureProtocol {
}

/// Create a future having the same underlying future as `other`.
public init(_ other: Future<Value>) {
self.box = other.box
public init(_ future: Future<Value>) {
self.box = future.box
}

public func upon(_ executor: Executor, execute body: @escaping(Value) -> Void) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Deferred/Promise.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ extension PromiseProtocol where Value == Void {
/// Filling a deferred event should usually be attempted only once.
///
/// - returns: Whether the promise was fulfilled.
@discardableResult @available(swift 4)
@discardableResult
func fill() -> Bool {
return fill(with: ())
}
Expand Down
66 changes: 33 additions & 33 deletions Sources/Task/ExistentialTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public final class Task<SuccessValue>: NSObject {
public let progress: Progress

/// Creates a task given a `future` and its `progress`.
public init(future: Future<Result>, progress: Progress) {
public init(_ future: Future<Result>, progress: Progress) {
self.future = future
self.progress = .taskRoot(for: progress)
}
Expand All @@ -57,21 +57,21 @@ public final class Task<SuccessValue>: NSObject {
///
/// `cancellation` will be called asynchronously, but not on any specific
/// queue. If you must do work on a specific queue, schedule work on it.
public convenience init(future base: Future<Result>, cancellation: (() -> Void)? = nil) {
let progress = Progress.wrappingSuccess(of: base, cancellation: cancellation)
self.init(future: base, progress: progress)
public convenience init(_ future: Future<Result>, uponCancel cancellation: (() -> Void)? = nil) {
let progress = Progress.wrappingSuccess(of: future, uponCancel: cancellation)
self.init(future, progress: progress)
}

/// Creates a task whose `upon(_:execute:)` methods use those of `base`.
public convenience init<OtherTask: TaskProtocol>(_ base: OtherTask, progress: Progress) where OtherTask.SuccessValue == SuccessValue {
let future = Future<Result>(task: base)
self.init(future: future, progress: progress)
public convenience init<Wrapped: TaskProtocol>(_ wrapped: Wrapped, progress: Progress) where Wrapped.SuccessValue == SuccessValue {
let future = Future<Result>(wrapped)
self.init(future, progress: progress)
}

/// Creates a task whose `upon(_:execute:)` methods use those of `base`.
public convenience init<OtherFuture: FutureProtocol>(success base: OtherFuture, progress: Progress) where OtherFuture.Value == SuccessValue {
let future = Future<Result>(success: base)
self.init(future: future, progress: progress)
public convenience init<Wrapped: FutureProtocol>(succeedsFrom wrapped: Wrapped, progress: Progress) where Wrapped.Value == SuccessValue {
let future = Future<Result>(succeedsFrom: wrapped)
self.init(future, progress: progress)
}
#else
private let cancellation: () -> Void
Expand All @@ -81,7 +81,7 @@ public final class Task<SuccessValue>: NSObject {
///
/// `cancellation` will be called asynchronously, but not on any specific
/// queue. If you must do work on a specific queue, schedule work on it.
public init(future: Future<Result>, cancellation: (() -> Void)? = nil) {
public init(_ future: Future<Result>, uponCancel cancellation: (() -> Void)? = nil) {
self.future = future
self.cancellation = cancellation ?? {}
}
Expand Down Expand Up @@ -143,18 +143,18 @@ extension Task {
///
/// `cancellation` will be called asynchronously, but not on any specific
/// queue. If you must do work on a specific queue, schedule work on it.
public convenience init<OtherTask: TaskProtocol>(_ base: OtherTask, cancellation: (() -> Void)? = nil) where OtherTask.SuccessValue == SuccessValue {
let future = Future<Result>(task: base)
public convenience init<Wrapped: TaskProtocol>(_ wrapped: Wrapped, uponCancel cancellation: (() -> Void)? = nil) where Wrapped.SuccessValue == SuccessValue {
let future = Future<Result>(wrapped)
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
let progress = Progress.wrappingSuccess(of: base, cancellation: cancellation)
self.init(future: future, progress: progress)
let progress = Progress.wrappingSuccess(of: wrapped, uponCancel: cancellation)
self.init(future, progress: progress)
#else
self.init(future: future) {
base.cancel()
self.init(future) {
wrapped.cancel()
cancellation?()
}

if base.isCancelled {
if wrapped.isCancelled {
markCancelled(using: cancellation)
}
#endif
Expand All @@ -164,43 +164,43 @@ extension Task {
///
/// `cancellation` will be called asynchronously, but not on any specific
/// queue. If you must do work on a specific queue, schedule work on it.
public convenience init<OtherFuture: FutureProtocol>(success base: OtherFuture, cancellation: (() -> Void)? = nil) where OtherFuture.Value == SuccessValue {
let future = Future<Result>(success: base)
public convenience init<Wrapped: FutureProtocol>(succeedsFrom wrapped: Wrapped, uponCancel cancellation: (() -> Void)? = nil) where Wrapped.Value == SuccessValue {
let future = Future<Result>(succeedsFrom: wrapped)
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
let progress = Progress.wrappingCompletion(of: base, cancellation: cancellation)
self.init(future: future, progress: progress)
let progress = Progress.wrappingCompletion(of: wrapped, uponCancel: cancellation)
self.init(future, progress: progress)
#else
self.init(future: future)
self.init(future, uponCancel: cancellation)
#endif
}

/// Creates an operation that has already completed with `value`.
public convenience init(success value: @autoclosure() throws -> SuccessValue) {
let future = Future<Result>(value: Result(from: value))
let future = Future<Result>(success: value)
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
self.init(future: future, progress: .noWork())
self.init(future, progress: .noWork())
#else
self.init(future: future, cancellation: nil)
self.init(future)
#endif
}

/// Creates an operation that has already failed with `error`.
public convenience init(failure error: Error) {
let future = Future<Result>(value: Result(failure: error))
let future = Future<Result>(failure: error)
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
self.init(future: future, progress: .noWork())
self.init(future, progress: .noWork())
#else
self.init(future: future, cancellation: nil)
self.init(future)
#endif
}

/// Creates a task having the same underlying operation as the `other` task.
public convenience init(_ other: Task<SuccessValue>) {
public convenience init(_ task: Task<SuccessValue>) {
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
self.init(future: other.future, progress: other.progress)
self.init(task.future, progress: task.progress)
#else
self.init(future: other.future, cancellation: other.cancellation)
if other.isCancelled {
self.init(task.future, uponCancel: task.cancellation)
if task.isCancelled {
markCancelled()
}
#endif
Expand Down
18 changes: 14 additions & 4 deletions Sources/Task/Task.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,25 @@ extension Future: TaskProtocol where Value: Either, Value.Left == Error {
public typealias SuccessValue = Value.Right

/// Create a future having the same underlying task as `other`.
public init<OtherTask: TaskProtocol>(task other: OtherTask) where OtherTask.SuccessValue == SuccessValue, OtherTask.FailureValue == FailureValue {
self = other as? Future<Value> ?? other.every {
public init<Wrapped: TaskProtocol>(_ wrapped: Wrapped) where Wrapped.SuccessValue == SuccessValue, Wrapped.FailureValue == FailureValue {
self = wrapped as? Future<Value> ?? wrapped.every {
$0.withValues(ifLeft: Value.init(left:), ifRight: Value.init(right:))
}
}

/// Create a future having the same underlying task as `other`.
public init<OtherFuture: FutureProtocol>(success other: OtherFuture) where OtherFuture.Value == SuccessValue {
self = other.every(per: Value.init(right:))
public init<Wrapped: FutureProtocol>(succeedsFrom wrapped: Wrapped) where Wrapped.Value == SuccessValue {
self = wrapped.every(per: Value.init(right:))
}

/// Creates an future having already filled successfully with `value`.
public init(success value: @autoclosure() throws -> SuccessValue) {
self.init(value: Value(from: value))
}

/// Creates an future having already failed with `error`.
public init(failure error: FailureValue) {
self.init(value: Value(left: error))
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/Task/TaskAndThen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ extension TaskProtocol {
}

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
return Task<NewTask.SuccessValue>(future: future, progress: progress)
return Task<NewTask.SuccessValue>(future, progress: progress)
#else
return Task<NewTask.SuccessValue>(future: future) {
return Task<NewTask.SuccessValue>(future) {
cancellationToken.fill(with: ())
}
#endif
Expand Down
6 changes: 3 additions & 3 deletions Sources/Task/TaskCollections.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private struct AllFilled<SuccessValue>: TaskProtocol {
if let task = future as? Task<Base.Element.SuccessValue> {
progress.adoptChild(task.progress, orphaned: false, pendingUnitCount: 1)
} else {
progress.adoptChild(.wrappingSuccess(of: future, cancellation: nil), orphaned: true, pendingUnitCount: 1)
progress.adoptChild(.wrappingSuccess(of: future), orphaned: true, pendingUnitCount: 1)
}
#endif

Expand Down Expand Up @@ -99,7 +99,7 @@ extension Collection where Element: TaskProtocol {
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
return Task(wrapper, progress: wrapper.progress)
#else
return Task(wrapper, cancellation: wrapper.cancel)
return Task(wrapper, uponCancel: wrapper.cancel)
#endif
}
}
Expand All @@ -120,7 +120,7 @@ extension Collection where Element: TaskProtocol, Element.SuccessValue == Void {
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
return Task(wrapper, progress: wrapper.progress)
#else
return Task(wrapper, cancellation: wrapper.cancel)
return Task(wrapper, uponCancel: wrapper.cancel)
#endif
}
}
4 changes: 2 additions & 2 deletions Sources/Task/TaskFallback.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ extension TaskProtocol {
}

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
return Task<SuccessValue>(future: future, progress: progress)
return Task<SuccessValue>(future, progress: progress)
#else
return Task<SuccessValue>(future: future, cancellation: cancel)
return Task<SuccessValue>(future, uponCancel: cancel)
#endif
}
}
4 changes: 2 additions & 2 deletions Sources/Task/TaskIgnore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ extension TaskProtocol {

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
if let progress = (self as? Task<SuccessValue>)?.progress {
return Task<Void>(future: future, progress: progress)
return Task<Void>(future, progress: progress)
}
#endif

return Task<Void>(future: future, cancellation: cancel)
return Task<Void>(future, uponCancel: cancel)
}
}
4 changes: 2 additions & 2 deletions Sources/Task/TaskMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ extension TaskProtocol {
}

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
return Task<NewSuccessValue>(future: future, progress: progress)
return Task<NewSuccessValue>(future, progress: progress)
#else
return Task<NewSuccessValue>(future: future, cancellation: cancel)
return Task<NewSuccessValue>(future, uponCancel: cancel)
#endif
}
}
12 changes: 6 additions & 6 deletions Sources/Task/TaskProgress.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ extension Progress {
}

/// A simple indeterminate progress with a cancellation function.
static func wrappingCompletion<OtherFuture: FutureProtocol>(of base: OtherFuture, cancellation: (() -> Void)?) -> Progress {
let totalUnitCount: Int64 = base.wait(until: .now()) != nil ? 0 : -1
static func wrappingCompletion<Wrapped: FutureProtocol>(of wrapped: Wrapped, uponCancel cancellation: (() -> Void)?) -> Progress {
let totalUnitCount: Int64 = wrapped.peek() != nil ? 0 : -1
let progress = Progress(totalUnitCount: totalUnitCount)

if let cancellation = cancellation {
Expand All @@ -216,7 +216,7 @@ extension Progress {
progress.isCancellable = false
}

base.upon(.global(qos: .utility)) { _ in
wrapped.upon(.global(qos: .utility)) { _ in
progress.totalUnitCount = 1
progress.completedUnitCount = 1
}
Expand All @@ -225,8 +225,8 @@ extension Progress {
}

/// A simple indeterminate progress with a cancellation function.
static func wrappingSuccess<OtherTask: TaskProtocol>(of base: OtherTask, cancellation: (() -> Void)? = nil) -> Progress {
switch (base as? Task<OtherTask.SuccessValue>, cancellation) {
static func wrappingSuccess<Wrapped: TaskProtocol>(of wrapped: Wrapped, uponCancel cancellation: (() -> Void)? = nil) -> Progress {
switch (wrapped as? Task<Wrapped.SuccessValue>, cancellation) {
case (let task?, nil):
return task.progress
case (let task?, let cancellation?):
Expand All @@ -235,7 +235,7 @@ extension Progress {
progress.adoptChild(task.progress, orphaned: false, pendingUnitCount: 1)
return progress
default:
return .wrappingCompletion(of: base, cancellation: cancellation)
return .wrappingCompletion(of: wrapped, uponCancel: cancellation)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Task/TaskPromise.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extension TaskProtocol where Self: PromiseProtocol, SuccessValue == Void {
///
/// - seealso: `PromiseProtocol.fill(with:)`
/// - seealso: `TaskProtocol.succeed(with:)`
@discardableResult @available(swift 4)
@discardableResult
public func succeed() -> Bool {
return fill(with: Value(right: ()))
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Task/TaskRecovery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ extension TaskProtocol {
}

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
return Task<SuccessValue>(future: future, progress: progress)
return Task<SuccessValue>(future, progress: progress)
#else
return Task<SuccessValue>(future: future, cancellation: cancel)
return Task<SuccessValue>(future, uponCancel: cancel)
#endif
}
}
1 change: 0 additions & 1 deletion Sources/Task/TaskResult.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ private enum TaskResultInitializerError: Error {

extension TaskResult where Value == Void {
/// Creates the success value.
@available(swift 4)
@_inlineable
public init() {
self = .success(())
Expand Down
4 changes: 2 additions & 2 deletions Tests/TaskTests/TaskComprehensiveTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private final class TaskProducer {
deferred.fill(with: .success(()))
}

return Task(future: Future(deferred), cancellation: {
return Task(deferred, uponCancel: {
deferred.fill(with: .failure(TaskProducerError.userCancelled))
})
}
Expand All @@ -114,7 +114,7 @@ private final class TaskProducer {
deferred.fill(with: .success((items)))
}

return Task(future: Future(deferred), cancellation: {
return Task(deferred, uponCancel: {
deferred.fill(with: .failure(TaskProducerError.userCancelled))
})
}
Expand Down
8 changes: 4 additions & 4 deletions Tests/TaskTests/TaskTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class TaskTests: CustomExecutorTestCase {

private func makeContrivedNextTask(for result: Int) -> Task<Int> {
let deferred = Deferred<Task<Int>.Result>()
let task = Task(deferred, cancellation: nil)
let task = Task(deferred)
afterShortDelay {
deferred.succeed(with: result * 2)
}
Expand Down Expand Up @@ -120,7 +120,7 @@ class TaskTests: CustomExecutorTestCase {
func testThatAndThenForwardsCancellationToSubsequentTask() {
let expect = expectation(description: "flatMapped task is cancelled")
let task = makeAnyFinishedTask().andThen(upon: executor) { _ -> Task<String> in
Task(future: .never) { expect.fulfill() }
Task(.never) { expect.fulfill() }
}

task.cancel()
Expand Down Expand Up @@ -237,7 +237,7 @@ class TaskTests: CustomExecutorTestCase {

func testThatTaskWrappingUnfilledIsIndeterminate() {
let deferred = Deferred<Task<Int>.Result>()
let wrappedTask = Task(deferred, cancellation: {})
let wrappedTask = Task(deferred)

XCTAssertFalse(wrappedTask.progress.isIndeterminate)
}
Expand Down Expand Up @@ -326,7 +326,7 @@ class TaskTests: CustomExecutorTestCase {
func testSimpleFutureCanBeUpgradedToTask() {
let deferred = Deferred<Int>()

let task = Task<Int>(success: deferred, cancellation: nil)
let task = Task<Int>(succeedsFrom: deferred)
let expect = expectation(that: task, succeedsWith: 42)

deferred.fill(with: 42)
Expand Down