userver: /data/code/userver/libraries/grpc-proto-structs/include/userver/grpc-proto-structs/client/stream.hpp Source File
Loading...
Searching...
No Matches
stream.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief Structs Reader/Writer stream wrappers over Vanilla streams.
5
6#include <userver/proto-structs/convert.hpp>
7#include <userver/ugrpc/client/stream.hpp>
8#include <userver/utils/box.hpp>
9
10#include <userver/grpc-proto-structs/client/stream_read_future.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace grpc_proto_structs::client {
15
16/// @brief proto-struct based Reader adapter.
17template <typename StructsResponse>
18class Reader final {
19public:
20 using ProtobufResponse = proto_structs::traits::CompatibleMessageType<StructsResponse>;
21 using ProtobufReader = ugrpc::client::Reader<ProtobufResponse>;
22
23 explicit Reader(ProtobufReader&& reader)
24 : reader_{std::move(reader)}
25 {}
26
27 Reader(Reader&&) = default;
28 Reader& operator=(Reader&&) = default;
29
30 /// @brief Await and read the next incoming message.
31 ///
32 /// Read protobuf message corresponding to Response with @ref ugrpc::client::Reader::Read
33 /// and construct response from it.
34 [[nodiscard]] std::optional<StructsResponse> Read() {
35 ProtobufResponse message;
36 if (reader_.Read(message)) {
37 StructsResponse response;
38 proto_structs::MessageToStruct(message, response);
39 return {response};
40 }
41 return std::nullopt;
42 ;
43 }
44
45 /// @brief Get call context, useful e.g. for accessing metadata.
46 ///
47 /// @see @ref ugrpc::client::Reader::GetContext.
48 ugrpc::client::CallContext& GetContext() { return reader_.GetContext(); }
49
50 /// @overload
51 ///
52 /// @see @ref ugrpc::client::Reader::GetContext.
53 const ugrpc::client::CallContext& GetContext() const { return reader_.GetContext(); }
54
55private:
56 ProtobufReader reader_;
57};
58
59/// @brief proto-struct based Writer adapter.
60template <typename StructsRequest, typename StructsResponse>
61class Writer final {
62public:
63 using ProtobufResponse = proto_structs::traits::CompatibleMessageType<StructsResponse>;
64 using ProtobufRequest = proto_structs::traits::CompatibleMessageType<StructsRequest>;
65
66 using ProtobufWriter = ugrpc::client::Writer<ProtobufRequest, ProtobufResponse>;
67
68 explicit Writer(ProtobufWriter&& writer)
69 : writer_{std::move(writer)}
70 {}
71
72 Writer(Writer&&) = default;
73 Writer& operator=(Writer&&) = default;
74
75 /// @brief Write the next outgoing message.
76 /// @note This version may move some fields from the request.
77 [[nodiscard]] bool Write(StructsRequest&& request) {
78 return writer_.Write(proto_structs::StructToMessage(std::move(request)));
79 }
80
81 /// @brief Write the next outgoing message.
82 /// @note This version preserves the original request object by copying necessary data.
83 [[nodiscard]] bool WriteCopy(const StructsRequest& request) {
84 return writer_.Write(proto_structs::StructToMessage(request));
85 }
86
87 /// @brief Write the next outgoing message and check result.
88 /// @note This version may move some fields from the request.
89 void WriteAndCheck(StructsRequest&& request) {
90 writer_.WriteAndCheck(proto_structs::StructToMessage(std::move(request)));
91 }
92
93 /// @brief Write the next outgoing message and check result.
94 /// @note This version preserves the original request object by copying necessary data.
95 void WriteCopyAndCheck(const StructsRequest& request) {
96 writer_.WriteAndCheck(proto_structs::StructToMessage(request));
97 }
98
99 /// @brief Complete the RPC successfully
100 StructsResponse Finish() { return proto_structs::MessageToStruct<StructsResponse>(writer_.Finish()); }
101
102 /// @brief Get call context, useful e.g. for accessing metadata.
103 ugrpc::client::CallContext& GetContext() { return writer_.GetContext(); }
104
105 /// @overload
106 const ugrpc::client::CallContext& GetContext() const { return writer_.GetContext(); }
107
108private:
109 ProtobufWriter writer_;
110};
111
112/// @brief proto-struct based ReaderWriter adapter.
113template <typename StructsRequest, typename StructsResponse>
114class ReaderWriter final {
115public:
116 using ProtobufResponse = proto_structs::traits::CompatibleMessageType<StructsResponse>;
117 using ProtobufRequest = proto_structs::traits::CompatibleMessageType<StructsRequest>;
118
119 using ProtobufReaderWriter = ugrpc::client::ReaderWriter<ProtobufRequest, ProtobufResponse>;
120
121 explicit ReaderWriter(ProtobufReaderWriter&& reader_writer)
122 : reader_writer_{std::move(reader_writer)}
123 {}
124
125 ReaderWriter(ReaderWriter&&) = default;
126 ReaderWriter& operator=(ReaderWriter&&) = default;
127
128 /// @brief Await and read the next incoming message.
129 ///
130 /// @see @ref ugrpc::client::ReaderWriter::Read.
131 [[nodiscard]] std::optional<StructsResponse> Read() {
132 ProtobufResponse message;
133 if (reader_writer_.Read(message)) {
134 StructsResponse response;
135 proto_structs::MessageToStruct(message, response);
136 return {response};
137 }
138 return std::nullopt;
139 }
140
141 /// @brief Return future to read next incoming result.
142 StreamReadFuture<StructsResponse> ReadAsync() { return {reader_writer_.ReadAsync(*response_), *response_}; }
143
144 /// @brief Write the next outgoing message.
145 ///
146 /// @see @ref ugrpc::client::ReaderWriter::Write.
147 [[nodiscard]] bool Write(const StructsRequest& request) {
148 return reader_writer_.Write(proto_structs::StructToMessage(request));
149 }
150
151 /// @brief Write the next outgoing message.
152 ///
153 /// @see @ref ugrpc::client::ReaderWriter::Write.
154 [[nodiscard]] bool Write(StructsRequest&& request) {
155 return reader_writer_.Write(proto_structs::StructToMessage(std::move(request)));
156 }
157
158 /// @brief Write the next outgoing message and check result.
159 ///
160 /// @see @ref ugrpc::client::ReaderWriter::WriteAndCheck.
161 void WriteAndCheck(const StructsRequest& request) {
162 reader_writer_.WriteAndCheck(proto_structs::StructToMessage(request));
163 }
164
165 /// @brief Write the next outgoing message and check result.
166 ///
167 /// @see @ref ugrpc::client::ReaderWriter::WriteAndCheck.
168 void WriteAndCheck(StructsRequest&& request) {
169 reader_writer_.WriteAndCheck(proto_structs::StructToMessage(std::move(request)));
170 }
171
172 /// @brief Announce end-of-output to the server.
173 ///
174 /// @see @ref ugrpc::client::ReaderWriter::WritesDone.
175 [[nodiscard]] bool WritesDone() { return reader_writer_.WritesDone(); }
176
177 /// @brief Get call context, useful e.g. for accessing metadata.
178 ///
179 /// @see @ref ugrpc::client::ReaderWriter::GetContext.
180 ugrpc::client::CallContext& GetContext() { return reader_writer_.GetContext(); }
181
182 /// @overload
183 ///
184 /// @see @ref ugrpc::client::ReaderWriter::GetContext.
185 const ugrpc::client::CallContext& GetContext() const { return reader_writer_.GetContext(); }
186
187private:
188 ProtobufReaderWriter reader_writer_;
189 utils::Box<ProtobufResponse> response_;
190};
191
192} // namespace grpc_proto_structs::client
193
194USERVER_NAMESPACE_END