-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathAsyncSequence+EraseToAnyAsyncSequence.swift
44 lines (35 loc) · 1.29 KB
/
AsyncSequence+EraseToAnyAsyncSequence.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//
// AsyncSequence+EraseToAnyAsyncSequence.swift
//
//
// Created by Thibault Wittemberg on 31/12/2021.
//
public extension AsyncSequence {
/// Type erase the AsyncSequence into an AnyAsyncSequence.
/// - Returns: A type erased AsyncSequence.
func eraseToAnyAsyncSequence() -> AnyAsyncSequence<Element> where Self: Sendable {
AnyAsyncSequence(self)
}
}
/// Type erased version of an AsyncSequence.
public struct AnyAsyncSequence<Element>: AsyncSequence {
public typealias AsyncIterator = AnyAsyncIterator<Element>
private let makeAsyncIteratorClosure: @Sendable () -> AsyncIterator
public init<Base: AsyncSequence>(_ base: Base) where Base.Element == Element, Base: Sendable {
self.makeAsyncIteratorClosure = { AnyAsyncIterator(base: base.makeAsyncIterator()) }
}
public func makeAsyncIterator() -> AsyncIterator {
self.makeAsyncIteratorClosure()
}
}
public struct AnyAsyncIterator<Element>: AsyncIteratorProtocol {
public typealias Element = Element
private let nextClosure: () async throws -> Element?
public init<Base: AsyncIteratorProtocol>(base: Base) where Base.Element == Element {
var mutableBase = base
self.nextClosure = { try await mutableBase.next() }
}
public mutating func next() async throws -> Element? {
try await self.nextClosure()
}
}