Created
November 21, 2022 06:54
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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