Coverage Report

Created: 2025-06-24 06:59

/src/grpc-swift/Sources/GRPC/ClientCalls/ResponsePartContainer.swift
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2020, 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
import NIOCore
17
import NIOHPACK
18
19
/// A container for RPC response parts.
20
internal struct ResponsePartContainer<Response> {
21
  /// The type of handler for response message part.
22
  enum ResponseHandler {
23
    case unary(EventLoopPromise<Response>)
24
    case stream((Response) -> Void)
25
  }
26
27
  var lazyInitialMetadataPromise: LazyEventLoopPromise<HPACKHeaders>
28
29
  /// A handler for response messages.
30
  let responseHandler: ResponseHandler
31
32
  /// A promise for the trailing metadata.
33
  var lazyTrailingMetadataPromise: LazyEventLoopPromise<HPACKHeaders>
34
35
  /// A promise for the call status.
36
  var lazyStatusPromise: LazyEventLoopPromise<GRPCStatus>
37
38
  /// Fail all promises - except for the status promise - with the given error status. Succeed the
39
  /// status promise.
40
0
  mutating func fail(with error: Error, status: GRPCStatus) {
41
0
    self.lazyInitialMetadataPromise.fail(error)
42
0
43
0
    switch self.responseHandler {
44
0
    case let .unary(response):
45
0
      response.fail(error)
46
0
    case .stream:
47
0
      ()
48
0
    }
49
0
    self.lazyTrailingMetadataPromise.fail(error)
50
0
    // We always succeed the status.
51
0
    self.lazyStatusPromise.succeed(status)
52
0
  }
53
54
  /// Make a response container for a unary response.
55
0
  init(eventLoop: EventLoop, unaryResponsePromise: EventLoopPromise<Response>) {
56
0
    self.lazyInitialMetadataPromise = eventLoop.makeLazyPromise()
57
0
    self.lazyTrailingMetadataPromise = eventLoop.makeLazyPromise()
58
0
    self.lazyStatusPromise = eventLoop.makeLazyPromise()
59
0
    self.responseHandler = .unary(unaryResponsePromise)
60
0
  }
61
62
  /// Make a response container for a response which is streamed.
63
0
  init(eventLoop: EventLoop, streamingResponseHandler: @escaping (Response) -> Void) {
64
0
    self.lazyInitialMetadataPromise = eventLoop.makeLazyPromise()
65
0
    self.lazyTrailingMetadataPromise = eventLoop.makeLazyPromise()
66
0
    self.lazyStatusPromise = eventLoop.makeLazyPromise()
67
0
    self.responseHandler = .stream(streamingResponseHandler)
68
0
  }
69
}