RPCAsyncSequence.swift 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright 2023, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /// A type-erasing `AsyncSequence`.
  17. public struct RPCAsyncSequence<
  18. Element: Sendable,
  19. Failure: Error
  20. >: AsyncSequence, @unchecked Sendable {
  21. // @unchecked Sendable is required because 'any' doesn't support composition with primary
  22. // associated types. (see: https://github.com/swiftlang/swift/issues/63877)
  23. //
  24. // To work around that limitation the 'init' requires that the async sequence being wrapped
  25. // is 'Sendable' but that constraint must be dropped internally. This is safe, the compiler just
  26. // can't prove it.
  27. @usableFromInline
  28. let _wrapped: any AsyncSequence<Element, Failure>
  29. /// Creates an ``RPCAsyncSequence`` by wrapping another `AsyncSequence`.
  30. @inlinable
  31. public init<Source: AsyncSequence<Element, Failure>>(
  32. wrapping other: Source
  33. ) where Source: Sendable {
  34. self._wrapped = other
  35. }
  36. @inlinable
  37. public func makeAsyncIterator() -> AsyncIterator {
  38. AsyncIterator(wrapping: self._wrapped.makeAsyncIterator())
  39. }
  40. public struct AsyncIterator: AsyncIteratorProtocol {
  41. @usableFromInline
  42. private(set) var iterator: any AsyncIteratorProtocol<Element, Failure>
  43. @inlinable
  44. init(
  45. wrapping other: some AsyncIteratorProtocol<Element, Failure>
  46. ) {
  47. self.iterator = other
  48. }
  49. @inlinable
  50. public mutating func next(
  51. isolation actor: isolated (any Actor)?
  52. ) async throws(Failure) -> Element? {
  53. try await self.iterator.next(isolation: `actor`)
  54. }
  55. @inlinable
  56. public mutating func next() async throws -> Element? {
  57. try await self.next(isolation: nil)
  58. }
  59. }
  60. }
  61. @available(*, unavailable)
  62. extension RPCAsyncSequence.AsyncIterator: Sendable {}