Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save inamiy/179413d4ff7bb97d037ee361ab104000 to your computer and use it in GitHub Desktop.
Save inamiy/179413d4ff7bb97d037ee361ab104000 to your computer and use it in GitHub Desktop.
AsyncSequence subprotocol with primary associated type, erase with existential, and check try-await element type
import Foundation
import _Concurrency
extension AsyncStream {
public init<S: AsyncSequence & Sendable>(
_ sequence: S,
bufferingPolicy limit: Continuation.BufferingPolicy = .unbounded
) where S.Element == Element {
self.init(bufferingPolicy: limit) { continuation in
let task = Task {
do {
for try await element in sequence {
continuation.yield(element)
}
} catch {}
continuation.finish()
}
let terminationClosure: @Sendable (Continuation.Termination) -> Void = { _ in
task.cancel()
}
continuation.onTermination = terminationClosure
}
}
}
// MARK: ----------------------------------------
// Using Swift 5.7 primary associated type
protocol MyAsyncSequence<Element>: AsyncSequence {}
extension AsyncStream: MyAsyncSequence {}
let stream = AsyncStream<Int> { nil }
let anyMySequence: any MyAsyncSequence<Int> = stream
// ERROR: x is Any, not Int
for try await x: Int in anyMySequence {
}
let mySeqStream = AsyncStream.init(anyMySequence) // NOTE: This `init` is type-erasure
// OK: x is Int
for try await x: Int in mySeqStream {
}
""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment