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
29 changes: 0 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,35 +54,6 @@ sendability of the underlying value.

The library comes with numerous helper APIs spread across the two Swift stream types:

* There are helpers that erase any `AsyncSequence` conformance to either concrete stream type.
This allows you to treat the stream type as a kind of "type erased" `AsyncSequence`.

For example, suppose you have a dependency client like this:

```swift
struct ScreenshotsClient {
var screenshots: () -> AsyncStream<Void>
}
```

Then you can construct a live implementation that "erases" the
`NotificationCenter.Notifications` async sequence to a stream:

```swift
extension ScreenshotsClient {
static let live = Self(
screenshots: {
NotificationCenter.default
.notifications(named: UIApplication.userDidTakeScreenshotNotification)
.map { _ in }
.eraseToStream() // ⬅️
}
)
}
```

Use `eraseToThrowingStream()` to propagate failures from throwing async sequences.

* Swift 5.9's `makeStream(of:)` functions have been back-ported. It can be handy in tests that need
to override a dependency endpoint that returns a stream:

Expand Down
12 changes: 12 additions & 0 deletions Sources/ConcurrencyExtras/AsyncStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ extension AsyncStream {
/// ```
///
/// - Parameter sequence: An async sequence.
@available(iOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, Never>', instead.")
@available(macOS, deprecated: 15, message: "Use 'any AsyncSequence<Element, Never>', instead.")
@available(tvOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, Never>', instead.")
@available(
watchOS, deprecated: 11, message: "Use 'any AsyncSequence<Element, Never>', instead."
)
public init<S: AsyncSequence>(_ sequence: S) where S.Element == Element, S: Sendable {
let lock = NSLock()
let iterator = UncheckedBox<S.AsyncIterator?>(wrappedValue: nil)
Expand Down Expand Up @@ -79,6 +85,12 @@ extension AsyncStream {
extension AsyncSequence {
/// Erases this async sequence to an async stream that produces elements till this sequence
/// terminates (or fails).
@available(iOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, Never>', instead.")
@available(macOS, deprecated: 15, message: "Use 'any AsyncSequence<Element, Never>', instead.")
@available(tvOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, Never>', instead.")
@available(
watchOS, deprecated: 11, message: "Use 'any AsyncSequence<Element, Never>', instead."
)
public func eraseToStream() -> AsyncStream<Element> where Self: Sendable {
AsyncStream(self)
}
Expand Down
16 changes: 16 additions & 0 deletions Sources/ConcurrencyExtras/AsyncThrowingStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ extension AsyncThrowingStream where Failure == Error {
/// terminates, rethrowing any failure.
///
/// - Parameter sequence: An async sequence.
@available(iOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, any Error>', instead.")
@available(
macOS, deprecated: 15, message: "Use 'any AsyncSequence<Element, any Error>', instead."
)
@available(tvOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, any Error>', instead.")
@available(
watchOS, deprecated: 11, message: "Use 'any AsyncSequence<Element, any Error>', instead."
)
public init<S: AsyncSequence>(_ sequence: S) where S.Element == Element, S: Sendable {
let lock = NSLock()
let iterator = UncheckedBox<S.AsyncIterator?>(wrappedValue: nil)
Expand Down Expand Up @@ -34,6 +42,14 @@ extension AsyncThrowingStream where Failure == Error {
extension AsyncSequence {
/// Erases this async sequence to an async throwing stream that produces elements till this
/// sequence terminates, rethrowing any error on failure.
@available(iOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, any Error>', instead.")
@available(
macOS, deprecated: 15, message: "Use 'any AsyncSequence<Element, any Error>', instead."
)
@available(tvOS, deprecated: 18, message: "Use 'any AsyncSequence<Element, any Error>', instead.")
@available(
watchOS, deprecated: 11, message: "Use 'any AsyncSequence<Element, any Error>', instead."
)
public func eraseToThrowingStream() -> AsyncThrowingStream<Element, Error> where Self: Sendable {
AsyncThrowingStream(self)
}
Expand Down
Loading