ClientRequest.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 namespace for request message types used by clients.
  17. public enum ClientRequest {}
  18. extension ClientRequest {
  19. /// A request created by the client for a single message.
  20. ///
  21. /// This is used for unary and server-streaming RPCs.
  22. ///
  23. /// See ``ClientRequest/Stream`` for streaming requests and ``ServerRequest/Single`` for the
  24. /// servers representation of a single-message request.
  25. ///
  26. /// ## Creating ``Single`` requests
  27. ///
  28. /// ```swift
  29. /// let request = ClientRequest.Single<String>(message: "Hello, gRPC!")
  30. /// print(request.metadata) // prints '[:]'
  31. /// print(request.message) // prints 'Hello, gRPC!'
  32. /// ```
  33. public struct Single<Message: Sendable>: Sendable {
  34. /// Caller-specified metadata to send to the server at the start of the RPC.
  35. ///
  36. /// Both gRPC Swift and its transport layer may insert additional metadata. Keys prefixed with
  37. /// "grpc-" are prohibited and may result in undefined behaviour. Transports may also insert
  38. /// their own metadata, you should avoid using key names which may clash with transport specific
  39. /// metadata. Note that transports may also impose limits in the amount of metadata which may
  40. /// be sent.
  41. public var metadata: Metadata
  42. /// The message to send to the server.
  43. public var message: Message
  44. /// Create a new single client request.
  45. ///
  46. /// - Parameters:
  47. /// - message: The message to send to the server.
  48. /// - metadata: Metadata to send to the server at the start of the request. Defaults to empty.
  49. public init(
  50. message: Message,
  51. metadata: Metadata = [:]
  52. ) {
  53. self.metadata = metadata
  54. self.message = message
  55. }
  56. }
  57. }
  58. extension ClientRequest {
  59. /// A request created by the client for a stream of messages.
  60. ///
  61. /// This is used for client-streaming and bidirectional-streaming RPCs.
  62. ///
  63. /// See ``ClientRequest/Single`` for single-message requests and ``ServerRequest/Stream`` for the
  64. /// servers representation of a streaming-message request.
  65. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  66. public struct Stream<Message: Sendable>: Sendable {
  67. /// Caller-specified metadata sent to the server at the start of the RPC.
  68. ///
  69. /// Both gRPC Swift and its transport layer may insert additional metadata. Keys prefixed with
  70. /// "grpc-" are prohibited and may result in undefined behaviour. Transports may also insert
  71. /// their own metadata, you should avoid using key names which may clash with transport specific
  72. /// metadata. Note that transports may also impose limits in the amount of metadata which may
  73. /// be sent.
  74. public var metadata: Metadata
  75. /// A closure which, when called, writes messages in the writer.
  76. ///
  77. /// The producer will only be consumed once by gRPC and therefore isn't required to be
  78. /// idempotent. If the producer throws an error then the RPC will be cancelled. Once the
  79. /// producer returns the request stream is closed.
  80. public var producer: @Sendable (RPCWriter<Message>) async throws -> Void
  81. /// Create a new streaming client request.
  82. ///
  83. /// - Parameters:
  84. /// - messageType: The type of message contained in this request, defaults to `Message.self`.
  85. /// - metadata: Metadata to send to the server at the start of the request. Defaults to empty.
  86. /// - producer: A closure which writes messages to send to the server. The closure is called
  87. /// at most once and may not be called.
  88. public init(
  89. of messageType: Message.Type = Message.self,
  90. metadata: Metadata = [:],
  91. producer: @escaping @Sendable (RPCWriter<Message>) async throws -> Void
  92. ) {
  93. self.metadata = metadata
  94. self.producer = producer
  95. }
  96. }
  97. }
  98. // MARK: - Conversion
  99. @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
  100. extension ClientRequest.Stream {
  101. @_spi(Testing)
  102. public init(single request: ClientRequest.Single<Message>) {
  103. self.init(metadata: request.metadata) {
  104. try await $0.write(request.message)
  105. }
  106. }
  107. }