userver
C++ Async Framework
Loading...
Searching...
No Matches
result.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/ugrpc/server/result.hpp
4
/// @brief @copybrief ugrpc::server::Result
5
6
#
include
<
optional
>
7
#
include
<
variant
>
8
9
#
include
<
grpcpp
/
support
/
status
.
h
>
10
11
#
include
<
userver
/
utils
/
assert
.
hpp
>
12
13
USERVER_NAMESPACE_BEGIN
14
15
namespace
ugrpc::server {
16
17
/// @brief Result type for service handlers (non server-streaming).
18
///
19
/// Provides a way to return one of:
20
/// 1. `Response` + `grpc::Status::OK`;
21
/// 2. error `grpc::Status`.
22
///
23
/// For server-streaming RPCs, see @ref ugrpc::server::StreamingResult.
24
template
<
typename
Response>
25
class
Result
{
26
public
:
27
/// Construct from `Response`, implies `OK` status.
28
/*implicit*/
Result
(Response&& response)
29
: result_{std::move(response)}
30
{}
31
32
/// Construct from `grpc::Status`, only error status is allowed.
33
/*implicit*/
Result
(grpc::Status&& status)
34
: result_{std::move(status)}
35
{
36
UINVARIANT
(!
GetErrorStatus
(
)
.ok(),
"Only error status is allowed, for OK status a response should be provided"
);
37
}
38
39
/// Construct from `grpc::Status`, only error status is allowed.
40
/*implicit*/
Result
(
const
grpc::Status& status)
41
: result_{status}
42
{
43
UINVARIANT
(!
GetErrorStatus
(
)
.ok(),
"Only error status is allowed, for OK status a response should be provided"
);
44
}
45
46
/// @returns `true` if the `Result` contains `Response`, as opposed to an error status.
47
bool
IsSuccess
()
const
{
return
std::holds_alternative<Response>(result_); }
48
49
/// @returns the contained error status.
50
/// @pre `IsSuccess() == false`.
51
grpc::Status&&
ExtractErrorStatus
() {
52
UINVARIANT
(!
IsSuccess
(
)
,
"ExtractErrorStatus is only allowed in case of error status"
);
53
return
std::move(std::get<grpc::Status>(result_));
54
}
55
56
/// @returns the contained error status.
57
/// @pre `IsSuccess() == false`.
58
const
grpc::Status&
GetErrorStatus
()
const
{
59
UINVARIANT
(!
IsSuccess
(
)
,
"GetErrorStatus is only allowed in case of error status"
);
60
return
std::get<grpc::Status>(result_);
61
}
62
63
/// @returns the contained response.
64
/// @pre `IsSuccess() == true`.
65
Response&&
ExtractResponse
() {
66
UINVARIANT
(
IsSuccess
(
)
,
"ExtractResponse is only allowed in case of OK status"
);
67
return
std::get<Response>(std::move(result_));
68
}
69
70
/// @returns the contained error status.
71
/// @pre `IsSuccess() == true`.
72
const
Response&
GetResponse
()
const
{
73
UINVARIANT
(
IsSuccess
(
)
,
"GetResponse is only allowed in case of OK status"
);
74
return
std::get<Response>(result_);
75
}
76
77
private
:
78
std::variant<Response, grpc::Status> result_;
79
};
80
81
/// @brief Special result type for server-streaming service handlers.
82
///
83
/// Provides a way to return one of:
84
/// 1. `grpc::Status::OK`;
85
/// 2. error `grpc::Status`;
86
/// 3. last response + `grpc::Status::OK`, sent in a single batch.
87
///
88
/// For non-server-streaming RPCs, see @ref ugrpc::server::Result.
89
template
<
typename
Response>
90
class
StreamingResult final {
91
public
:
92
/// Construct from `grpc::Status` (which can be `OK` or an error status).
93
/*implicit*/
StreamingResult
(grpc::Status&& status)
94
: status_{std::move(status)}
95
{}
96
97
/// Construct from `grpc::Status` (which can be `OK` or an error status).
98
/*implicit*/
StreamingResult
(
const
grpc::Status& status)
99
: status_{status}
100
{}
101
102
/// Construct from last response. Allows to send last response and `OK` status coalesced in a single batch.
103
/*implicit*/
StreamingResult
(Response&& last_response)
104
: last_response_(std::move(last_response))
105
{}
106
107
/// @returns `true` if the `StreamingResult` contains `OK` status, possibly with a last response.
108
bool
IsSuccess
()
const
{
return
status_.ok(); }
109
110
/// @returns the contained status, which can be `OK` or an error status.
111
grpc::Status&&
ExtractStatus
() {
return
std::move(status_); }
112
113
/// @returns the contained status, which can be `OK` or an error status.
114
const
grpc::Status&
GetStatus
()
const
{
return
status_; }
115
116
/// @returns `true` if the `StreamingResult` contains last response, which implies `OK` status.
117
bool
HasLastResponse
()
const
{
return
last_response_.has_value(); }
118
119
/// @returns the contained last response.
120
/// @pre `HasLastResponse() == true`.
121
Response&&
ExtractLastResponse
() {
122
UINVARIANT
(
HasLastResponse
(
)
,
"There is no last response in the StreamingResult"
);
123
return
std::move(last_response_).value();
124
}
125
126
/// @returns the contained last response.
127
/// @pre `HasLastResponse() == true`.
128
const
Response&
GetLastResponse
()
const
{
129
UINVARIANT
(
HasLastResponse
(
)
,
"There is no last response in the StreamingResult"
);
130
return
last_response_.value();
131
}
132
133
private
:
134
std::optional<Response> last_response_;
135
grpc::Status status_{grpc::Status::OK};
136
};
137
138
}
// namespace ugrpc::server
139
140
USERVER_NAMESPACE_END
userver
ugrpc
server
result.hpp
Generated on Tue Jan 27 2026 16:47:18 for userver by
Doxygen
1.13.2