// // AsyncPrependSequence.swift // // // Created by Thibault Wittemberg on 31/12/2021. // public extension AsyncSequence { /// Prepends an element to the upstream async sequence. /// /// ``` /// let sourceSequence = AsyncLazySequence([1, 2, 3]) /// let prependSequence = sourceSequence.prepend(0) /// /// for try await element in prependSequence { /// print(element) /// } /// /// // will print: /// // Element is 0 /// // Element is 1 /// // Element is 2 /// // Element is 3 /// ``` /// /// - Parameter element: The element to prepend. /// - Returns: The async sequence prepended with the element. func prepend(_ element: @Sendable @autoclosure @escaping () -> Element) -> AsyncPrependSequence { AsyncPrependSequence(self, prependElement: element()) } } public struct AsyncPrependSequence: AsyncSequence { public typealias Element = Base.Element public typealias AsyncIterator = Iterator private var base: Base private var prependElement: @Sendable () -> Element public init( _ base: Base, prependElement: @Sendable @autoclosure @escaping () -> Element ) { self.base = base self.prependElement = prependElement } public func makeAsyncIterator() -> AsyncIterator { Iterator( base: self.base.makeAsyncIterator(), prependElement: self.prependElement ) } public struct Iterator: AsyncIteratorProtocol { var base: Base.AsyncIterator var prependElement: () async throws -> Element var hasBeenDelivered = false public init( base: Base.AsyncIterator, prependElement: @escaping () async throws -> Element ) { self.base = base self.prependElement = prependElement } public mutating func next() async throws -> Element? { guard !Task.isCancelled else { return nil } if !self.hasBeenDelivered { self.hasBeenDelivered = true return try await prependElement() } return try await self.base.next() } } } extension AsyncPrependSequence: Sendable where Base: Sendable {}