2 #include <rapidjson/document.h> 3 #include "../utils.hpp" 24 template <JTag tag,
class =
void>
struct JTagRepr {
using type = void; };
40 constexpr
static JTag tag = tag_;
45 template <JTag type, JTag nested_type = JTag::None,
class Extra =
void>
47 static_assert(type !=
JTag::None,
"Extracted type must exist");
50 using Repr = std::conditional_t<type != JTag::Array, JTagRepr_t<type, Extra>, std::vector<SubRepr>>;
51 using Ret = std::optional<Repr>;
52 auto error = [&](
auto... args) {
return json_res.error(args...), Ret{std::nullopt}; };
55 auto& ret_val = ret.emplace();
58 static_assert(nested_type !=
JTag::None,
"Sub-extracted type must exist");
60 if (!el_json.IsArray())
62 const auto el_jsonarr = el_json.GetArray();
63 ret_val.reserve(el_jsonarr.Size());
64 for (
const auto& sub_el : el_jsonarr) {
65 auto res = extract_param_val<nested_type, JTag::None>(sub_el, json_res);
67 return Ret{std::nullopt};
68 ret_val.push_back(std::move(*res));
71 static_assert(nested_type ==
JTag::None,
"Sub-extracted type shall not exist");
73 if (!el_json.IsBool())
75 ret_val = el_json.GetBool();
79 ret_val = el_json.GetInt();
81 if (!el_json.IsUint())
83 ret_val = el_json.GetUint();
85 if (!(el_json.IsInt() || el_json.IsInt64()))
87 ret_val = el_json.IsInt64() ? el_json.GetInt64() : el_json.GetInt();
89 if (!(el_json.IsUint() || el_json.IsUint64()))
91 ret_val = el_json.IsUint64() ? el_json.GetUint64() : el_json.GetUint();
93 if (!el_json.IsFloat())
95 ret_val = el_json.GetFloat();
97 if (!el_json.IsDouble())
99 ret_val = el_json.GetDouble();
101 if (!el_json.IsString())
103 ret_val = std::string{el_json.GetString(), el_json.GetStringLength()};
105 if (!el_json.IsString())
107 const auto enum_opt = Repr::from_string({el_json.GetString(), el_json.GetStringLength()});
109 return Ret{std::nullopt};
116 template <JTag type, JTag nested_type = JTag::None,
class Extra =
void>
117 auto extract_param(
const rapidjson::Value& val, gsl::czstring<> name,
JsonRes& json_res,
bool consider_optional =
false) noexcept
118 -> decltype(
extract_param_val<type, nested_type, Extra>(
std::declval<decltype(val)>(), json_res)) {
119 using Ret = decltype(extract_param_val<type, nested_type, Extra>(std::declval<decltype(val)>(), json_res));
120 auto error = [&](
auto... args) {
return json_res.error(args...), std::nullopt; };
121 const auto el_it = val.FindMember(name);
122 if (el_it == val.MemberEnd()) {
123 if (consider_optional) {
130 const auto& el_json = el_it->value;
131 return extract_param_val<type, nested_type, Extra>(el_json, json_res);
134 template <JTag tag, JTag nested_type_ = JTag::None,
class Extra =
void>
struct WArg {
138 constexpr
static auto nested_type = nested_type_;
141 bool optional =
false;
144 template <
size_t... I,
class... Args>
146 using Tup = std::tuple<
typename Args::Ret...>;
147 std::optional<Tup> ret{};
148 auto& vals = ret.emplace();
150 if constexpr (
sizeof...(args) > 1) {
152 return json_res.
error(0), decltype(ret){std::nullopt};
153 auto proc_parm = [&](
auto warg,
auto ic) {
155 using Extra =
typename JTagRev::Extra;
156 constexpr
JTag tag = JTagRev::tag;
157 constexpr
JTag nested_tag = decltype(warg)::nested_type;
158 constexpr
auto idx = decltype(ic)::value;
159 const auto res = extract_param<tag, nested_tag, Extra>(val, warg.name, json_res);
161 std::get<idx>(vals) = std::move(*res);
162 return static_cast<bool>(res);
164 return (proc_parm(args, std::integral_constant<size_t, I>{}) && ...) ? ret : std::nullopt;
165 }
else if constexpr (
sizeof...(args) == 1) {
166 auto proc_parm = [&](
auto warg) {
168 using Extra =
typename JTagRev::Extra;
169 constexpr
JTag tag = JTagRev::tag;
170 constexpr
JTag nested_tag = decltype(warg)::nested_type;
171 const auto res = extract_param_val<tag, nested_tag, Extra>(val, json_res);
173 std::get<0>(vals) = std::move(*res);
174 return static_cast<bool>(res);
176 return (proc_parm(args) && ...) ? ret : std::nullopt;
178 return std::optional{std::tuple<>{}};
182 template <
class... Args>
auto wrap_fcn_args(
const rapidjson::Value& val,
JsonRes& json_res, Args... args) noexcept {
183 return wrap_fcn_args_impl(val, json_res, std::index_sequence_for<Args...>{}, args...);
186 template <
class Fcn,
class... Args>
auto wrap_fcn(
const rapidjson::Value& val,
JsonRes& json_res, Fcn fcn, Args... args) noexcept {
188 return tup ? std::optional{std::apply(fcn, *tup)} : std::nullopt;
typename JTagRepr< tag, Extra >::type JTagRepr_t
Definition: json2virt.hpp:43
unsigned long long type
Definition: json2virt.hpp:30
auto wrap_fcn(const rapidjson::Value &val, JsonRes &json_res, Fcn fcn, Args...args) noexcept
Definition: json2virt.hpp:186
Definition: json2virt.hpp:24
void error(int code)
Definition: json_utils.hpp:57
float type
Definition: json2virt.hpp:31
std::string type
Definition: json2virt.hpp:33
::JTagRepr< tag, Extra > JTagRepr
Definition: json2virt.hpp:135
JTag
Definition: json2virt.hpp:9
Definition: json2virt.hpp:134
unsigned type
Definition: json2virt.hpp:28
void type
Definition: json2virt.hpp:24
long type
Definition: json2virt.hpp:27
RemoveOptional_t< decltype(extract_param_val< tag, nested_type_, Extra >(std::declval< const rapidjson::Value & >(), std::declval< JsonRes & >()))> Ret
Definition: json2virt.hpp:137
auto wrap_fcn_args_impl(const rapidjson::Value &val, JsonRes &json_res, std::index_sequence< I... > is, Args...args) noexcept
Definition: json2virt.hpp:145
auto wrap_fcn_args(const rapidjson::Value &val, JsonRes &json_res, Args...args) noexcept
Definition: json2virt.hpp:182
std::optional< virt::TypedParams > json_to_typed_parameters(const rapidjson::Value &val)
Definition: json2virt.cpp:3
Definition: json_utils.hpp:21
bool type
Definition: json2virt.hpp:26
typename RemoveOptional< OptT >::type RemoveOptional_t
Definition: utility.hpp:33
Definition: json2virt.hpp:36
long long type
Definition: json2virt.hpp:29
auto extract_param_val(const rapidjson::Value &el_json, JsonRes &json_res) noexcept
Definition: json2virt.hpp:46
double type
Definition: json2virt.hpp:32
gsl::czstring name
Definition: json2virt.hpp:140
auto extract_param(const rapidjson::Value &val, gsl::czstring<> name, JsonRes &json_res, bool consider_optional=false) noexcept-> decltype(extract_param_val< type, nested_type, Extra >(std::declval< decltype(val)>(), json_res))
Definition: json2virt.hpp:117
F type
Definition: json2virt.hpp:34