Files
swift-mirror/stdlib/public/Concurrency/AsyncIteratorProtocol.swift
Chris Adamson af4ebb4c46 Provide doc comments for AsyncSequence and related types (#37383)
* First draft docs for iterator, sequence type.

Also drop(while:), to get a feel for the AsyncSequence->AsyncSequence cases.

* Source docs for contains and reduce.

* Docs for methods in AsyncSequence.

This covers all the methods that return a single value. Still working on the extension methods that return new sequences.

* Early source docs for dropFirst(_:) and its type

* Correct doc format for dropFirst(_:).

* Prefix, plus some fixes.

* Docs for prefix(while:).

* Apply Philippe's snippet fixes.

* First draft docs on the map sequences.

Plus miscellaneous fixes throughout.

* Show result of flatMap example.

* More explicit cancellation guidance.

* Convert snippets to trailing closures.

* Correct misplaced doc comments.

* Apply suggestions from code review

Co-authored-by: Philippe Hausler <phausler@apple.com>

* Apply editorial feedback.

* Apply additional editorial feedback.

* Apply suggestions from code review

Co-authored-by: bjlanier <blanier@apple.com>

* Apply further editorial feedback.

Co-authored-by: Chris Adamson <cadamson@apple.com>
Co-authored-by: Philippe Hausler <phausler@apple.com>
Co-authored-by: bjlanier <blanier@apple.com>
2021-05-14 10:16:36 -04:00

98 lines
3.8 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import Swift
/// A type that that asychronously supplies the values of a sequence one at a
/// time.
///
/// The `AsyncIteratorProtocol` defines the type returned by the
/// `makeAsyncIterator()` method of the `AsyncSequence` protocol. In short,
/// the iterator is what produces the asynchronous sequence's values. The
/// protocol defines a single asynchronous method, `next()`, which either
/// produces the next element of the sequence, or returns `nil` to signal
/// the end of the sequence.
///
/// To implement your own `AsyncSequence`, implement a wrapped type that
/// conforms to `AsyncIteratorProtocol`. The following example shows a `Counter`
/// type that uses an inner iterator to monotonically generate `Int` values
/// until reaching a `howHigh` value. While this example isn't itself
/// asychronous, it shows the shape of a custom sequence and iterator, and how
/// to use it as if it were asynchronous:
///
/// struct Counter : AsyncSequence {
/// typealias Element = Int
/// let howHigh: Int
///
/// struct AsyncIterator : AsyncIteratorProtocol {
/// let howHigh: Int
/// var current = 1
/// mutating func next() async -> Int? {
/// // A genuinely asychronous implementation uses the `Task`
/// // API to check for cancellation here and return early.
/// guard current <= howHigh else {
/// return nil
/// }
///
/// let result = current
/// current += 1
/// return result
/// }
/// }
///
/// func makeAsyncIterator() -> AsyncIterator {
/// return AsyncIterator(howHigh: howHigh)
/// }
/// }
///
/// At the call site, this looks like:
///
/// for await i in Counter(howHigh: 10) {
/// print(i, terminator: " ")
/// }
/// // Prints: 1 2 3 4 5 6 7 8 9 10
///
/// ### End of Iteration
///
/// The iterator returns `nil` to indicate the end of the sequence. After
/// returning `nil` (or throwing an error) from `next()`, the iterator enters
/// a terminal state, and all future calls to `next()` must return `nil`.
///
/// ### Cancellation
///
/// Types conforming to `AsyncIteratorProtocol` should use the cancellation
/// primitives provided by Swift's `Task` API. The iterator can choose how to
/// handle and respond to cancellation, including:
///
/// - Checking the `isCancelled` value of the current `Task` inside `next()`
/// and returning `nil` to terminate the sequence.
/// - Calling `checkCancellation()` on the `Task`, which throws a
/// `CancellationError`.
/// - Implementing `next()` with a
/// `withTaskCancellationHandler(handler:operation:)` invocation to
/// immediately react to cancellation.
///
/// If the iterator needs to clean up on cancellation, it can do so after
/// checking for cancellation as described above, or in `deinit` if it's
/// a reference type.
@available(SwiftStdlib 5.5, *)
@rethrows
public protocol AsyncIteratorProtocol {
associatedtype Element
/// Asynchronously advances to the next element and returns it, or ends the
/// sequence if there is no next element.
///
/// - Returns: The next element, if it exists, or `nil` to signal the end of
/// the sequence.
mutating func next() async throws -> Element?
}