@@ -3,8 +3,79 @@ import AsyncAlgorithms
3
3
@available ( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * )
4
4
extension AsyncSequence {
5
5
6
- /// Returns the array of the elements of the asynchronous sequence.
7
- @inlinable package func collect( ) async rethrows -> [ Element ] {
8
- try await reduce ( into: [ ] ) { $0. append ( $1) }
6
+ /// Collects all elements of an `AsyncSequence` into an array.
7
+ ///
8
+ /// This method consumes the entire asynchronous sequence and accumulates its elements into a single array.
9
+ /// It returns `nil` if the task is cancelled before any elements are emitted. If the task is cancelled
10
+ /// after emitting elements, the collected elements are still returned. If the sequence completes without
11
+ /// producing any elements, an empty array is returned (unless cancelled).
12
+ ///
13
+ /// Rethrows any error thrown by the underlying asynchronous sequence.
14
+ ///
15
+ /// - Returns: An array of elements from the sequence, or `nil` if the task was cancelled before producing any elements.
16
+ ///
17
+ /// ### Usage Examples
18
+ ///
19
+ /// Collecting elements from a regular sequence:
20
+ /// ```swift
21
+ /// let sequence = [1, 2, 3].async
22
+ /// let result = await sequence.collect()
23
+ /// // result == [1, 2, 3]
24
+ /// ```
25
+ ///
26
+ /// Collecting from an empty sequence:
27
+ /// ```swift
28
+ /// let stream = AsyncStream<Int> { $0.finish() }
29
+ /// let result = await stream.collect()
30
+ /// // result == []
31
+ /// ```
32
+ ///
33
+ /// Handling cancellation:
34
+ /// ```swift
35
+ /// let task = Task {
36
+ /// let stream = AsyncStream<Int> { _ in }
37
+ /// return await stream.collect()
38
+ /// }
39
+ /// task.cancel()
40
+ /// let result = await task.value
41
+ /// // result == nil
42
+ /// ```
43
+ ///
44
+ /// Cancellation after yielding some elements:
45
+ /// ```swift
46
+ /// let task = Task {
47
+ /// let stream = AsyncStream<Int> {
48
+ /// for i in 1...3 {
49
+ /// $0.yield(i)
50
+ /// }
51
+ /// }
52
+ /// return await stream.collect()
53
+ /// }
54
+ /// task.cancel()
55
+ /// let result = await task.value
56
+ /// // result == [1, 2, 3]
57
+ /// ```
58
+ ///
59
+ /// Handling errors:
60
+ /// ```swift
61
+ /// struct MyError: Error {}
62
+ ///
63
+ /// let stream = AsyncThrowingStream<Int, Error> {
64
+ /// throw MyError()
65
+ /// }
66
+ ///
67
+ /// do {
68
+ /// _ = try await stream.collect()
69
+ /// } catch {
70
+ /// print("Caught error: \(error)") // Caught error: MyError
71
+ /// }
72
+ /// ```
73
+ @inlinable package func collect( ) async rethrows -> [ Element ] ? {
74
+ let elements = try await reduce ( into: [ ] ) { $0. append ( $1) }
75
+ return if elements. isEmpty {
76
+ Task . isCancelled ? nil : [ ]
77
+ } else {
78
+ elements
79
+ }
9
80
}
10
81
}
0 commit comments