Skip to content
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Please check the [releases](https://github.com/mochidev/AsyncSequenceReader/rele

```swift
dependencies: [
.package(url: "https://github.com/mochidev/AsyncSequenceReader.git", .upToNextMinor(from: "0.4.0")),
.package(url: "https://github.com/mochidev/AsyncSequenceReader.git", .upToNextMinor(from: "0.4.1")),
],
...
targets: [
Expand Down
6 changes: 6 additions & 0 deletions Sources/AsyncSequenceReader/AsyncBufferedIterator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ public struct AsyncBufferedIterator<BaseIterator: AsyncIteratorProtocol>: AsyncI
}

extension AsyncBufferedIterator: Sendable where BaseIterator.Element: Sendable {}

extension AsyncSequence {
public func makeBufferedIterator() -> AsyncBufferedIterator<AsyncIterator> {
AsyncBufferedIterator(makeAsyncIterator())
}
}
2 changes: 1 addition & 1 deletion Sources/AsyncSequenceReader/AsyncReadSequence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ extension AsyncIteratorProtocol {
results = try await sequenceTransform(readSequence)
wrappedIterator = readSequence.baseIterator
}
precondition(wrappedIterator.unconsumedBuffer.isEmpty, "A transform was requested, but the sequence was left in a state where the next value will never be read (fix: Use AnyReadableSequence(iterator) instead of calling `.transform` on `iterator` directly)")
precondition(wrappedIterator.unconsumedBuffer.isEmpty, "A transform was requested, but the sequence was left in a state where the next value will never be read (fix: Use `sequence.makeBufferedIterator()` instead of calling `.transform` on `iterator` directly)")
self = wrappedIterator.baseIterator

return results
Expand Down
31 changes: 31 additions & 0 deletions Tests/AsyncSequenceReaderTests/AsyncBufferedIteratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,37 @@ import Testing
#expect(await bufferedIterator.next() == nil)
}

@Test func bufferIteratorFromStreamConstructor() async throws {
let testStream = AsyncStream<Int> { continuation in
for value in 0..<10 {
continuation.yield(value)
}
continuation.finish()
}

var iterator = testStream.makeBufferedIterator()

#expect(await iterator.next() == 0)
#expect(await iterator.next() == 1)
#expect(await iterator.next() == 2)
#expect(await iterator.next() == 3)
#expect(await iterator.next() == 4)
#expect(await iterator.hasMoreData() == true)
#expect(await iterator.hasMoreData() == true)
#expect(await iterator.hasMoreData() == true)
#expect(await iterator.next() == 5)
#expect(try await iterator.nonIsolatedNext() == 6)
#expect(await iterator.next() == 7)
#expect(await iterator.next() == 8)
#expect(await iterator.hasMoreData() == true)
#expect(await iterator.next() == 9)
#expect(await iterator.hasMoreData() == false)
#expect(await iterator.next() == nil)
#expect(await iterator.hasMoreData() == false)
#expect(await iterator.hasMoreData() == false)
#expect(await iterator.next() == nil)
}

@Test func bufferIteratorFromTestSequence() async throws {
let testStream = TestSequence(base: 0..<10)

Expand Down
4 changes: 2 additions & 2 deletions Tests/AsyncSequenceReaderTests/AsyncSequenceReaderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ import Testing
})
}
#if DEBUG
#expect(result?.standardErrorUTF8Lines.first == "AsyncSequenceReader/AsyncReadSequence.swift:42: Precondition failed: A transform was requested, but the sequence was left in a state where the next value will never be read (fix: Use AnyReadableSequence(iterator) instead of calling `.transform` on `iterator` directly)")
#expect(result?.standardErrorUTF8Lines.first == "AsyncSequenceReader/AsyncReadSequence.swift:42: Precondition failed: A transform was requested, but the sequence was left in a state where the next value will never be read (fix: Use `sequence.makeBufferedIterator()` instead of calling `.transform` on `iterator` directly)")
#endif
}

Expand All @@ -313,7 +313,7 @@ import Testing
})
}
#if DEBUG
#expect(result?.standardErrorUTF8Lines.first == "AsyncSequenceReader/AsyncReadSequence.swift:42: Precondition failed: A transform was requested, but the sequence was left in a state where the next value will never be read (fix: Use AnyReadableSequence(iterator) instead of calling `.transform` on `iterator` directly)")
#expect(result?.standardErrorUTF8Lines.first == "AsyncSequenceReader/AsyncReadSequence.swift:42: Precondition failed: A transform was requested, but the sequence was left in a state where the next value will never be read (fix: Use `sequence.makeBufferedIterator()` instead of calling `.transform` on `iterator` directly)")
#endif
}
}