mirror of
https://github.com/qicosmos/rest_rpc.git
synced 2026-08-29 08:34:47 +08:00
custom codec
This commit is contained in:
+41
-11
@@ -5,18 +5,44 @@
|
||||
#include <charconv>
|
||||
#include <msgpack.hpp>
|
||||
|
||||
namespace rest_rpc {
|
||||
namespace user_codec {
|
||||
struct rest_adl_tag {};
|
||||
} // namespace user_codec
|
||||
|
||||
struct msgpack_codec {
|
||||
namespace rest_rpc {
|
||||
namespace detail {
|
||||
template <typename T, typename... Args>
|
||||
struct has_user_pack : std::false_type {};
|
||||
|
||||
template <typename... Args>
|
||||
struct has_user_pack<
|
||||
std::void_t<
|
||||
// AdlTag{} trigger ADL lookup user_codec namespace
|
||||
decltype(serialize(std::declval<user_codec::rest_adl_tag>(),
|
||||
std::declval<Args>()...))>,
|
||||
Args...> : std::true_type {};
|
||||
|
||||
template <typename... Args>
|
||||
inline constexpr bool has_user_pack_v = has_user_pack<void, Args...>::value;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct rpc_codec {
|
||||
template <typename... Args> inline static auto pack_args(Args &&...args) {
|
||||
if constexpr (sizeof...(Args) == 0) {
|
||||
return std::string_view{};
|
||||
} else if constexpr (sizeof...(Args) == 1 && util::is_basic_v<Args...>) {
|
||||
return pack_one(std::forward<Args>(args)...);
|
||||
} else {
|
||||
msgpack::sbuffer buffer(2 * 1024);
|
||||
msgpack::pack(buffer, std::forward_as_tuple(std::forward<Args>(args)...));
|
||||
return std::string(buffer.data(), buffer.size());
|
||||
if constexpr (detail::has_user_pack_v<Args...>) {
|
||||
return serialize(user_codec::rest_adl_tag{},
|
||||
std::forward<Args>(args)...);
|
||||
} else {
|
||||
msgpack::sbuffer buffer(2 * 1024);
|
||||
msgpack::pack(buffer,
|
||||
std::forward_as_tuple(std::forward<Args>(args)...));
|
||||
return std::string(buffer.data(), buffer.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +59,16 @@ struct msgpack_codec {
|
||||
} else if constexpr (std::is_same_v<std::string_view, T>) {
|
||||
return data;
|
||||
} else {
|
||||
try {
|
||||
static msgpack::unpacked msg;
|
||||
msgpack::unpack(msg, data.data(), data.size());
|
||||
return msg.get().as<T>();
|
||||
} catch (...) {
|
||||
throw std::invalid_argument("unpack failed: Args not match!");
|
||||
if constexpr (detail::has_user_pack_v<T>) {
|
||||
return deserialize<T>(user_codec::rest_adl_tag{}, data);
|
||||
} else {
|
||||
try {
|
||||
static msgpack::unpacked msg;
|
||||
msgpack::unpack(msg, data.data(), data.size());
|
||||
return msg.get().as<T>();
|
||||
} catch (...) {
|
||||
throw std::invalid_argument("unpack failed: Args not match!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ private:
|
||||
template <typename R, typename... Args>
|
||||
asio::awaitable<call_result<R>> call_impl(rest_rpc_header &header,
|
||||
Args &&...args) {
|
||||
auto buf = msgpack_codec::pack_args(std::forward<Args>(args)...);
|
||||
auto buf = rpc_codec::pack_args(std::forward<Args>(args)...);
|
||||
header.body_len = buf.size();
|
||||
if (cross_ending_) {
|
||||
prepare_for_send(header);
|
||||
@@ -227,10 +227,10 @@ private:
|
||||
result.ec = (rpc_errc)socket_->body_[0];
|
||||
if constexpr (!std::is_void_v<R>) {
|
||||
if constexpr (util::is_basic_v<R>) {
|
||||
result.value = msgpack_codec::unpack<R>(std::string_view(
|
||||
result.value = rpc_codec::unpack<R>(std::string_view(
|
||||
socket_->body_.data() + 1, resp_header.body_len - 1));
|
||||
} else {
|
||||
auto tp = msgpack_codec::unpack<std::tuple<R>>(std::string_view(
|
||||
auto tp = rpc_codec::unpack<std::tuple<R>>(std::string_view(
|
||||
socket_->body_.data() + 1, resp_header.body_len - 1));
|
||||
result.value = std::move(std::get<0>(tp));
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ asio::awaitable<std::error_code> rpc_context::response(Args &&...args) {
|
||||
co_return make_error_code(rpc_errc::rpc_context_init_failed);
|
||||
}
|
||||
|
||||
rpc_result result(msgpack_codec::pack_args(std::forward<Args>(args)...));
|
||||
rpc_result result(rpc_codec::pack_args(std::forward<Args>(args)...));
|
||||
has_response_ = true;
|
||||
co_return co_await conn_->response(result);
|
||||
}
|
||||
|
||||
@@ -148,15 +148,15 @@ private:
|
||||
} else {
|
||||
if constexpr (std::is_void_v<Self>) {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
ret = msgpack_codec::pack_args(co_await f());
|
||||
ret = rpc_codec::pack_args(co_await f());
|
||||
} else {
|
||||
ret = msgpack_codec::pack_args(f());
|
||||
ret = rpc_codec::pack_args(f());
|
||||
}
|
||||
} else {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
ret = msgpack_codec::pack_args(co_await (*self.*f)());
|
||||
ret = rpc_codec::pack_args(co_await (*self.*f)());
|
||||
} else {
|
||||
ret = msgpack_codec::pack_args((*self.*f)());
|
||||
ret = rpc_codec::pack_args((*self.*f)());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,32 +169,30 @@ private:
|
||||
if constexpr (is_void_v<R>) {
|
||||
if constexpr (std::is_void_v<Self>) {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
co_await f(msgpack_codec::unpack<Arg>(str));
|
||||
co_await f(rpc_codec::unpack<Arg>(str));
|
||||
} else {
|
||||
f(msgpack_codec::unpack<Arg>(str));
|
||||
f(rpc_codec::unpack<Arg>(str));
|
||||
}
|
||||
} else {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
co_await (*self.*f)(msgpack_codec::unpack<Arg>(str));
|
||||
co_await (*self.*f)(rpc_codec::unpack<Arg>(str));
|
||||
} else {
|
||||
(*self.*f)(msgpack_codec::unpack<Arg>(str));
|
||||
(*self.*f)(rpc_codec::unpack<Arg>(str));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if constexpr (std::is_void_v<Self>) {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
ret = msgpack_codec::pack_args(
|
||||
co_await f(msgpack_codec::unpack<Arg>(str)));
|
||||
ret = rpc_codec::pack_args(co_await f(rpc_codec::unpack<Arg>(str)));
|
||||
} else {
|
||||
ret = msgpack_codec::pack_args(f(msgpack_codec::unpack<Arg>(str)));
|
||||
ret = rpc_codec::pack_args(f(rpc_codec::unpack<Arg>(str)));
|
||||
}
|
||||
} else {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
ret = msgpack_codec::pack_args(
|
||||
co_await (*self.*f)(msgpack_codec::unpack<Arg>(str)));
|
||||
ret = rpc_codec::pack_args(
|
||||
co_await (*self.*f)(rpc_codec::unpack<Arg>(str)));
|
||||
} else {
|
||||
ret = msgpack_codec::pack_args(
|
||||
(*self.*f)(msgpack_codec::unpack<Arg>(str)));
|
||||
ret = rpc_codec::pack_args((*self.*f)(rpc_codec::unpack<Arg>(str)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,7 +202,7 @@ private:
|
||||
template <typename R, typename Args, typename F, typename Self>
|
||||
asio::awaitable<void> handle_more_args(std::string_view str, const F &f,
|
||||
rpc_result &ret, Self *self) {
|
||||
auto tp = msgpack_codec::unpack<Args>(str);
|
||||
auto tp = rpc_codec::unpack<Args>(str);
|
||||
if constexpr (std::is_void_v<R>) {
|
||||
if constexpr (std::is_void_v<Self>) {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
@@ -230,19 +228,19 @@ private:
|
||||
} else {
|
||||
if constexpr (std::is_void_v<Self>) {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
ret = msgpack_codec::pack_args(co_await std::apply(f, tp));
|
||||
ret = rpc_codec::pack_args(co_await std::apply(f, tp));
|
||||
} else {
|
||||
ret = msgpack_codec::pack_args(std::apply(f, tp));
|
||||
ret = rpc_codec::pack_args(std::apply(f, tp));
|
||||
}
|
||||
} else {
|
||||
if constexpr (is_awaitable_v<R>) {
|
||||
ret = msgpack_codec::pack_args(co_await std::apply(
|
||||
ret = rpc_codec::pack_args(co_await std::apply(
|
||||
[self, &f](auto &&...args) {
|
||||
return (*self.*f)(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
tp));
|
||||
} else {
|
||||
ret = msgpack_codec::pack_args(std::apply(
|
||||
ret = rpc_codec::pack_args(std::apply(
|
||||
[self, &f](auto &&...args) {
|
||||
return (*self.*f)(std::forward<decltype(args)>(args)...);
|
||||
},
|
||||
|
||||
@@ -113,8 +113,7 @@ public:
|
||||
auto conns = get_connections();
|
||||
for (auto &[_, conn] : conns) {
|
||||
if (conn->topic_id() == id) {
|
||||
co_await conn->response(msgpack_codec::pack_args(std::forward<T>(t)),
|
||||
id);
|
||||
co_await conn->response(rpc_codec::pack_args(std::forward<T>(t)), id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user