Skip to content

Commit 9de4774

Browse files
committed
Add ResponseStream
1 parent 4cbd5c3 commit 9de4774

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Foundation
2+
3+
struct ResponseStream<Chunk>: AsyncSequence {
4+
func makeAsyncIterator() -> Stream.AsyncIterator {
5+
stream.makeAsyncIterator()
6+
}
7+
8+
typealias Stream = AsyncThrowingStream<Chunk, Error>
9+
typealias AsyncIterator = Stream.AsyncIterator
10+
typealias Element = Chunk
11+
12+
struct LineContent {
13+
let chunk: Chunk?
14+
let done: Bool
15+
}
16+
17+
let stream: Stream
18+
19+
init(result: URLSession.AsyncBytes, lineExtractor: @escaping (String) throws -> LineContent) {
20+
stream = AsyncThrowingStream<Chunk, Error> { continuation in
21+
let task = Task {
22+
do {
23+
for try await line in result.lines {
24+
if Task.isCancelled { break }
25+
let content = try lineExtractor(line)
26+
if let chunk = content.chunk {
27+
continuation.yield(chunk)
28+
}
29+
30+
if content.done { break }
31+
}
32+
continuation.finish()
33+
} catch {
34+
continuation.finish(throwing: error)
35+
result.task.cancel()
36+
}
37+
}
38+
continuation.onTermination = { _ in
39+
task.cancel()
40+
result.task.cancel()
41+
}
42+
}
43+
}
44+
}
45+

0 commit comments

Comments
 (0)