10 -> std::expected<Response, error::RpcError> {
12 if (
auto result = r.ValidateResponse(); !result) {
13 return std::unexpected(result.error());
19 const nlohmann::json& result,
const std::optional<RequestId>&
id)
21 nlohmann::json response = {{
"jsonrpc",
kJsonRpcVersion}, {
"result", result}};
23 std::visit([&response](
const auto& v) { response[
"id"] = v; }, *id);
25 return Response{std::move(response)};
29 RpcErrorCode code,
const std::optional<RequestId>&
id) ->
Response {
32 nlohmann::json error = {
33 {
"code",
static_cast<int>(err.
Code())}, {
"message", err.
Message()}};
34 nlohmann::json response = {{
"jsonrpc",
kJsonRpcVersion}, {
"error", error}};
36 std::visit([&response](
const auto& v) { response[
"id"] = v; }, *id);
38 response[
"id"] =
nullptr;
40 return Response{std::move(response)};
45 nlohmann::json error_json = error.to_json();
46 return CreateError(error_json,
id);
50 const nlohmann::json& error,
const std::optional<RequestId>&
id)
52 nlohmann::json response = {{
"jsonrpc",
kJsonRpcVersion}, {
"error", error}};
54 std::visit([&response](
const auto& v) { response[
"id"] = v; }, *id);
56 return Response{std::move(response)};
60 return response_.contains(
"result");
65 throw std::runtime_error(
"Response is not a success response");
67 return response_[
"result"];
72 throw std::runtime_error(
"Response is not an error response");
74 return response_[
"error"];
78 if (!response_.contains(
"id") || response_[
"id"].is_null()) {
82 const auto&
id = response_[
"id"];
84 return id.get<std::string>();
86 return id.get<int64_t>();
93auto Response::ValidateResponse() const
94 -> std::expected<
void, error::
RpcError> {
95 if (!response_.contains(
"jsonrpc") ||
98 RpcErrorCode::kInvalidRequest,
"Invalid JSON-RPC version");
101 if (!response_.contains(
"result") && !response_.contains(
"error")) {
103 RpcErrorCode::kInvalidRequest,
104 "Response must contain either 'result' or 'error' field");
107 if (response_.contains(
"result") && response_.contains(
"error")) {
109 RpcErrorCode::kInvalidRequest,
110 "Response cannot contain both 'result' and 'error' fields");
113 if (response_.contains(
"error")) {
114 const auto& error = response_[
"error"];
115 if (!error.contains(
"code") || !error.contains(
"message")) {
117 RpcErrorCode::kInvalidRequest,
118 "Error object must contain 'code' and 'message' fields");
static auto CreateSuccess(const nlohmann::json &result, const std::optional< RequestId > &id) -> Response
auto GetResult() const -> const nlohmann::json &
static auto CreateError(RpcErrorCode code, const std::optional< RequestId > &id=std::nullopt) -> Response
auto GetId() const -> std::optional< RequestId >
static auto FromJson(const nlohmann::json &json) -> std::expected< Response, error::RpcError >
auto IsSuccess() const -> bool
auto GetError() const -> const nlohmann::json &
auto ToJson() const -> nlohmann::json
static auto FromCode(RpcErrorCode code, std::string message="") -> RpcError
auto Code() const -> RpcErrorCode
auto Message() const -> std::string
static auto UnexpectedFromCode(RpcErrorCode code, std::string message="") -> std::unexpected< RpcError >
std::variant< int64_t, std::string > RequestId
constexpr std::string_view kJsonRpcVersion