@use crate::data::RPC; @use crate::generators::cpp_s::*; @(rpc: &RPC) template void json_get(const rapidjson::Value &j, const char *key, T &v); template void json_get_inner(const rapidjson::Value&, T &v) = delete; @for (ty, jty) in JSON_INNER_IMPLS { template<> inline void json_get_inner(const rapidjson::Value &member, @ty &v) @{ if (!member.Is@(jty)()) throw std::exception@{@}; v = member.Get@(jty)(); @}} template inline void json_get_inner(const rapidjson::Value &member, std::optional &v) @{ if (member.IsNull()) v = std::nullopt; else @{ T t; json_get_inner(member, t); v = std::move(t); @} @} template inline void json_get_inner(const rapidjson::Value &member, std::vector &v) @{ if (!member.IsArray()) throw std::exception@{@}; for (const auto &j : member.GetArray()) @{ T t; json_get_inner(j, t); v.push_back(std::move(t)); @} @} @for s in &rpc.structs { template<> inline void json_get_inner(const rapidjson::Value &__j, mrpc::@s.name &v) @{ using namespace mrpc; @for f in &s.fields { json_get<@ty_to_str(&f.ty)>(__j, "@f.name", v.@f.name); }@} } @for e in &rpc.enums { template<> inline void json_get_inner(const rapidjson::Value &j, mrpc::@e.name &v) @{ json_get_inner(j, (std::uint64_t&)v); @} mrpc::MRPCJWriter& operator >>(const mrpc::@e.name &v, mrpc::MRPCJWriter &w) @{ w.Uint64((std::uint64_t)v); return w; @} } template inline void json_get(const rapidjson::Value &j, const char *key, T &v) @{ auto member = j.FindMember(key); if (member == j.MemberEnd()) throw std::exception@{@}; json_get_inner(member->value, v); @} namespace mrpc @{ @for s in &rpc.structs { MRPCJWriter& @(s.name)::operator >>(MRPCJWriter &__w) const @{ __w.StartObject(); @for f in &s.fields { __w.Key("@f.name", @f.name.len()); @json_write(&f) } __w.EndObject(); return __w; @} @(s.name)& @(s.name)::operator <<(const rapidjson::Value &__j) @{ json_get_inner<@(s.name)>(__j, *this); return *this; @} }