@@ -55,39 +55,89 @@ extension AsyncSequence {
55
55
}
56
56
}
57
57
58
+ struct AsyncEitherSequence < Base: AsyncSequence > : AsyncSequence {
59
+ typealias Element = Either
60
+ typealias AsyncIterator = Iterator
61
+
62
+ enum Either {
63
+ case first( Base . Element )
64
+ case second( Base . Element )
65
+ }
66
+
67
+ let base : Base
68
+ let factory : ( Base . Element ) -> Either
69
+
70
+ func makeAsyncIterator( ) -> AsyncIterator {
71
+ Iterator (
72
+ base: self . base. makeAsyncIterator ( ) ,
73
+ factory: self . factory
74
+ )
75
+ }
76
+
77
+ struct Iterator : AsyncIteratorProtocol {
78
+
79
+ var base : Base . AsyncIterator
80
+ let factory : ( Base . Element ) -> Either
81
+
82
+ mutating func next( ) async rethrows -> Element ? {
83
+ guard let element = try await self . base. next ( ) else {
84
+ return nil
85
+ }
86
+ return self . factory ( element)
87
+ }
88
+ }
89
+
90
+ }
91
+
58
92
/// An `AsyncSequence` that chunks elements into collected `RangeReplaceableCollection` instances by either count or a signal from another `AsyncSequence`.
59
93
public struct AsyncChunksOfCountOrSignalSequence < Base: AsyncSequence , Collected: RangeReplaceableCollection , Signal: AsyncSequence > : AsyncSequence , Sendable where Collected. Element == Base . Element , Base: Sendable , Signal: Sendable , Base. AsyncIterator: Sendable , Signal. AsyncIterator: Sendable , Base. Element: Sendable , Signal. Element: Sendable {
60
94
61
95
public typealias Element = Collected
62
96
97
+ enum Either {
98
+ case first( Base . Element )
99
+ case second( Signal . Element )
100
+ }
101
+
63
102
/// The iterator for a `AsyncChunksOfCountOrSignalSequence` instance.
64
103
public struct Iterator : AsyncIteratorProtocol , Sendable {
65
104
let count : Int ?
66
- var state : Merge2StateMachine < Base , Signal >
67
- init ( base: Base . AsyncIterator , count: Int ? , signal: Signal . AsyncIterator ) {
105
+ let state : MergeStateMachine < Either >
106
+ init ( base: Base , count: Int ? , signal: Signal ) {
68
107
self . count = count
69
- self . state = Merge2StateMachine ( base, terminatesOnNil: true , signal)
108
+ let eitherBase = base. map { Either . first ( $0) }
109
+ let eitherSignal = signal. map { Either . second ( $0) }
110
+ self . state = MergeStateMachine ( eitherBase, terminatesOnNil: true , eitherSignal)
70
111
}
71
-
112
+
72
113
public mutating func next( ) async rethrows -> Collected ? {
73
- var result : Collected ?
74
- while let next = try await state. next ( ) {
75
- switch next {
76
- case . first( let element) :
77
- if result == nil {
78
- result = Collected ( )
79
- }
80
- result!. append ( element)
81
- if result? . count == count {
82
- return result
83
- }
84
- case . second( _) :
85
- if result != nil {
86
- return result
87
- }
88
- }
114
+ var collected : Collected ?
115
+
116
+ loop: while true {
117
+ let next = await state. next ( )
118
+
119
+ switch next {
120
+ case . termination:
121
+ break loop
122
+ case . element( let result) :
123
+ let element = try result. _rethrowGet ( )
124
+ switch element {
125
+ case . first( let element) :
126
+ if collected == nil {
127
+ collected = Collected ( )
128
+ }
129
+ collected!. append ( element)
130
+ if collected? . count == count {
131
+ return collected
132
+ }
133
+ case . second( _) :
134
+ if collected != nil {
135
+ return collected
136
+ }
137
+ }
89
138
}
90
- return result
139
+ }
140
+ return collected
91
141
}
92
142
}
93
143
@@ -105,6 +155,6 @@ public struct AsyncChunksOfCountOrSignalSequence<Base: AsyncSequence, Collected:
105
155
}
106
156
107
157
public func makeAsyncIterator( ) -> Iterator {
108
- return Iterator ( base: base. makeAsyncIterator ( ) , count: count, signal: signal. makeAsyncIterator ( ) )
158
+ return Iterator ( base: base, count: count, signal: signal)
109
159
}
110
160
}
0 commit comments