Skip to content

Commit d3bf67c

Browse files
committed
Add bodyParts computed prop to StreamingClientResponse
1 parent 968f4dc commit d3bf67c

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

Sources/GRPCCore/Call/Client/ClientResponse.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,4 +382,13 @@ extension StreamingClientResponse {
382382
return RPCAsyncSequence.throwing(error)
383383
}
384384
}
385+
386+
/// Returns the body parts (i.e. `messages` and `trailingMetadata`) returned from the server.
387+
///
388+
/// For rejected RPCs (in other words, where ``accepted`` is `failure`), this method throws an `RPCError`.
389+
public var bodyParts: RPCAsyncSequence<Contents.BodyPart, any Error> {
390+
get throws {
391+
try self.accepted.get().bodyParts
392+
}
393+
}
385394
}

Tests/GRPCCoreTests/Call/Client/ClientResponseTests.swift

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ final class ClientResponseTests: XCTestCase {
5353
XCTAssertEqual(response.trailingMetadata, ["bar": "baz"])
5454
}
5555

56-
func testAcceptedStreamResponseConvenienceMethods() async throws {
56+
func testAcceptedStreamResponseConvenienceMethods_Messages() async throws {
5757
let response = StreamingClientResponse(
5858
of: String.self,
5959
metadata: ["foo": "bar"],
@@ -73,6 +73,29 @@ final class ClientResponseTests: XCTestCase {
7373
XCTAssertEqual(messages, ["foo", "bar", "baz"])
7474
}
7575

76+
func testAcceptedStreamResponseConvenienceMethods_BodyParts() async throws {
77+
let response = StreamingClientResponse(
78+
of: String.self,
79+
metadata: ["foo": "bar"],
80+
bodyParts: RPCAsyncSequence(
81+
wrapping: AsyncThrowingStream {
82+
$0.yield(.message("foo"))
83+
$0.yield(.message("bar"))
84+
$0.yield(.message("baz"))
85+
$0.yield(.trailingMetadata(["baz": "baz"]))
86+
$0.finish()
87+
}
88+
)
89+
)
90+
91+
XCTAssertEqual(response.metadata, ["foo": "bar"])
92+
let bodyParts = try await response.bodyParts.collect()
93+
XCTAssertEqual(
94+
bodyParts,
95+
[.message("foo"), .message("bar"), .message("baz"), .trailingMetadata(["baz": "baz"])]
96+
)
97+
}
98+
7699
func testRejectedStreamResponseConvenienceMethods() async throws {
77100
let error = RPCError(code: .aborted, message: "error message", metadata: ["bar": "baz"])
78101
let response = StreamingClientResponse(of: String.self, error: error)
@@ -182,3 +205,21 @@ final class ClientResponseTests: XCTestCase {
182205
}
183206
}
184207
}
208+
209+
extension StreamingClientResponse.Contents.BodyPart: Equatable where Message: Equatable {
210+
static func == (
211+
lhs: StreamingClientResponse.Contents.BodyPart,
212+
rhs: StreamingClientResponse.Contents.BodyPart
213+
) -> Bool {
214+
switch (lhs, rhs) {
215+
case (.message(let lhsMessage), .message(let rhsMessage)):
216+
return lhsMessage == rhsMessage
217+
218+
case (.trailingMetadata(let lhsMetadata), .trailingMetadata(let rhsMetadata)):
219+
return lhsMetadata == rhsMetadata
220+
221+
default:
222+
return false
223+
}
224+
}
225+
}

0 commit comments

Comments
 (0)