41#include <nlohmann/json.hpp>
52 using serial_t = nlohmann::json;
53 using bytes_t = std::string;
59 [[nodiscard]]
static std::string to_bytes(nlohmann::json&& serial_obj)
61 return std::move(serial_obj).dump();
64 [[nodiscard]]
static std::optional<nlohmann::json> from_bytes(std::string&& bytes)
70 obj = nlohmann::json::parse(std::move(bytes));
72 catch (
const nlohmann::json::parse_error&)
82 if (obj.contains(
"except_type"))
84 if (obj[
"except_type"] != 0 && !obj.contains(
"err_mesg"))
90 return std::make_optional(std::move(obj));
93 if (
const auto fname_it = obj.find(
"func_name");
94 fname_it == obj.end() || !fname_it->is_string() || fname_it->empty())
99 if (
const auto args_it = obj.find(
"args"); args_it == obj.end() || !args_it->is_array())
104 return std::make_optional(std::move(obj));
107 static nlohmann::json empty_object() {
return nlohmann::json::object(); }
109 template<
typename R,
typename... Args>
110 [[nodiscard]]
static nlohmann::json serialize_pack(
111 const detail::packed_func<R, Args...>& pack)
113 nlohmann::json obj{};
114 obj[
"func_name"] = pack.get_func_name();
115 obj[
"args"] = nlohmann::json::array();
116 auto& arg_arr = obj[
"args"];
117 arg_arr.get_ref<nlohmann::json::array_t&>().reserve(
sizeof...(Args));
119 detail::for_each_tuple(pack.get_args(),
120 [&arg_arr](
auto&& elem)
121 { push_args(std::forward<decltype(elem)>(elem), arg_arr); });
125 obj[
"except_type"] = pack.get_except_type();
126 obj[
"err_mesg"] = pack.get_err_mesg();
130 if constexpr (!std::is_void_v<R>)
133 push_arg(pack.get_result(), obj[
"result"]);
139 template<
typename R,
typename... Args>
140 [[nodiscard]]
static detail::packed_func<R, Args...> deserialize_pack(
141 const nlohmann::json& serial_obj)
143 const auto& args_val = serial_obj[
"args"];
144 [[maybe_unused]]
unsigned arg_counter = 0;
145 typename detail::packed_func<R, Args...>::args_t args{ parse_args<Args>(
146 args_val, arg_counter)... };
148 if constexpr (std::is_void_v<R>)
150 detail::packed_func<void, Args...> pack(serial_obj[
"func_name"], std::move(args));
152 if (serial_obj.contains(
"except_type"))
154 pack.set_exception(serial_obj[
"err_mesg"],
155 static_cast<exception_type
>(serial_obj[
"except_type"]));
162 if (serial_obj.contains(
"result") && !serial_obj[
"result"].is_null())
164 return detail::packed_func<R, Args...>(serial_obj[
"func_name"],
165 parse_arg<R>(serial_obj[
"result"]), std::move(args));
168 detail::packed_func<R, Args...> pack(
169 serial_obj[
"func_name"], std::nullopt, std::move(args));
171 if (serial_obj.contains(
"except_type"))
173 pack.set_exception(serial_obj[
"err_mesg"],
174 static_cast<exception_type
>(serial_obj[
"except_type"]));
181 [[nodiscard]]
static std::string get_func_name(
const nlohmann::json& serial_obj)
183 return serial_obj[
"func_name"];
186 [[nodiscard]]
static rpc_exception extract_exception(
const nlohmann::json& serial_obj)
188 return rpc_exception{ serial_obj.at(
"err_mesg").get<std::string>(),
189 static_cast<exception_type
>(serial_obj.at(
"except_type").get<
int>()) };
192 static void set_exception(nlohmann::json& serial_obj,
const rpc_exception& ex)
194 serial_obj[
"except_type"] = ex.get_type();
195 serial_obj[
"err_mesg"] = ex.what();
199 static nlohmann::json serialize(
const T& val) =
delete;
202 static T deserialize(
const nlohmann::json& serial_obj) =
delete;
207 [[nodiscard]]
static constexpr bool validate_arg(
const nlohmann::json& arg)
noexcept
209 if constexpr (std::is_same_v<T, bool>)
211 return arg.is_boolean();
213 else if constexpr (std::is_integral_v<T>)
215 return arg.is_number() && !arg.is_number_float();
217 else if constexpr (std::is_floating_point_v<T>)
219 return arg.is_number_float();
221 else if constexpr (std::is_same_v<T, std::string>)
223 return arg.is_string();
225 else if constexpr (detail::is_container_v<T>)
227 return arg.is_array();
231 return !arg.is_null();
236 [[nodiscard]]
static std::string mismatch_string(
237 std::string&& expect_type,
const nlohmann::json& arg)
239 return {
"njson expected type: " + std::move(expect_type)
240 +
", got type: " + arg.type_name() };
244 static void push_arg(T&& arg, nlohmann::json& obj)
246 using no_ref_t = std::remove_cv_t<std::remove_reference_t<T>>;
248 if constexpr (std::is_arithmetic_v<no_ref_t> || std::is_same_v<no_ref_t, std::string>)
250 obj = std::forward<T>(arg);
252 else if constexpr (detail::is_container_v<no_ref_t>)
254 obj = nlohmann::json::array();
255 obj.get_ref<nlohmann::json::array_t&>().reserve(arg.size());
257 for (
auto&& val : arg)
259 push_args(std::forward<
decltype(val)>(val), obj);
262 else if constexpr (detail::is_serializable_v<njson_adapter, no_ref_t>)
264 obj = no_ref_t::template serialize<njson_adapter>(std::forward<T>(arg));
268 obj = serialize<no_ref_t>(std::forward<T>(arg));
273 static void push_args(T&& arg, nlohmann::json& obj_arr)
275 nlohmann::json tmp{};
276 push_arg(std::forward<T>(arg), tmp);
277 obj_arr.push_back(std::move(tmp));
282 [[nodiscard]]
static std::remove_cv_t<std::remove_reference_t<T>> parse_arg(
283 const nlohmann::json& arg)
285 using no_ref_t = std::remove_cv_t<std::remove_reference_t<T>>;
287 if (!validate_arg<T>(arg))
292 if constexpr (std::is_arithmetic_v<no_ref_t> || std::is_same_v<no_ref_t, std::string>)
294 return arg.get<no_ref_t>();
296 else if constexpr (detail::is_container_v<no_ref_t>)
298 using value_t =
typename no_ref_t::value_type;
300 no_ref_t container{};
301 container.reserve(arg.size());
302 unsigned arg_counter = 0;
304 for (
const auto& val : arg)
306 container.push_back(parse_args<value_t>(val, arg_counter));
311 else if constexpr (detail::is_serializable_v<njson_adapter, no_ref_t>)
313 return no_ref_t::template deserialize<njson_adapter>(arg);
317 return deserialize<no_ref_t>(arg);
323 [[nodiscard]]
static std::remove_cv_t<std::remove_reference_t<T>> parse_args(
324 const nlohmann::json& arg_arr,
unsigned& index)
326 if (index >= arg_arr.size())
331 const auto& arg = arg_arr.is_array() ? arg_arr[index++] : arg_arr;
332 return parse_arg<T>(arg);
Definition: rpc_njson.hpp:57
Top-level namespace for rpc.hpp classes and functions.
Definition: rpc.hpp:88