Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save brianmwadime/c8a2622835067ad09ce2bfd6ab13a38f to your computer and use it in GitHub Desktop.

Select an option

Save brianmwadime/c8a2622835067ad09ce2bfd6ab13a38f to your computer and use it in GitHub Desktop.

Revisions

  1. @inamiy inamiy created this gist Nov 21, 2022.
    53 changes: 53 additions & 0 deletions AsyncSequence-subprotocol-try-await-element-type.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    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 {

    }



    ""