Implemented generics properly, updated cpp generator to use operator<< and operator>> for json parsing
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
@use crate::data::RPC;
 | 
			
		||||
@use crate::generators::cpp_s::*;
 | 
			
		||||
@use super::cpp_server_json_cpp;
 | 
			
		||||
@use super::cpp_server_json_cxx;
 | 
			
		||||
 | 
			
		||||
@(header_name: &str, rpc: &RPC)
 | 
			
		||||
#include "@header_name"
 | 
			
		||||
@@ -8,7 +8,9 @@
 | 
			
		||||
#include <corvusoft/restbed/resource.hpp>
 | 
			
		||||
#include <corvusoft/restbed/request.hpp>
 | 
			
		||||
 | 
			
		||||
@:cpp_server_json_cpp(rpc)
 | 
			
		||||
using namespace mrpc;
 | 
			
		||||
 | 
			
		||||
@:cpp_server_json_cxx(rpc)
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void send_msg(const std::shared_ptr<restbed::Session> &c, const T &v) @{
 | 
			
		||||
@@ -55,7 +57,7 @@ mrpc::MRPCStreamImpl::MRPCStreamImpl(const std::shared_ptr<restbed::Session> &co
 | 
			
		||||
 | 
			
		||||
void mrpc::MRPCStreamImpl::close() const noexcept @{ conn->close("data:null\n\n"); @}
 | 
			
		||||
bool mrpc::MRPCStreamImpl::is_open() const noexcept @{ return conn->is_open(); @}
 | 
			
		||||
@for s in streams_required(rpc) {template<> void MRPCStream<mrpc::@s>::send(const mrpc::@s &v) const noexcept @{ send_sse_msg(conn, v); @}
 | 
			
		||||
@for s in streams_required(rpc) {template<> void MRPCStream<@s>::send(const @s &v) const noexcept @{ send_sse_msg(conn, v); @}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mrpc::MRPCServer::MRPCServer(std::shared_ptr<restbed::Resource> &r) @{
 | 
			
		||||
@@ -75,7 +77,8 @@ void mrpc::MRPCServer::msg_handler(const std::shared_ptr<restbed::Session> __c,
 | 
			
		||||
    if (__j.HasParseError())
 | 
			
		||||
        throw std::exception@{@};
 | 
			
		||||
    std::string __service, __method;
 | 
			
		||||
    json_get(__j, "service", __service); json_get(__j, "method", __method);
 | 
			
		||||
    __service << json_get(__j, "service");
 | 
			
		||||
    __method << json_get(__j, "method");
 | 
			
		||||
    auto __data_member = __j.FindMember("data");
 | 
			
		||||
    if (__data_member == __j.MemberEnd() || !__data_member->value.IsObject())
 | 
			
		||||
        throw std::exception@{@};
 | 
			
		||||
@@ -84,7 +87,7 @@ void mrpc::MRPCServer::msg_handler(const std::shared_ptr<restbed::Session> __c,
 | 
			
		||||
@for (mi, m) in s.methods.iter().enumerate() {@if mi > 0 { else }else{        }if (__method == "@m.name") @{
 | 
			
		||||
            @if m.ret_stream {auto __stream = MRPCStream<@ty_to_str(m.ret.as_ref().unwrap())>@{__c@};
 | 
			
		||||
            }
 | 
			
		||||
@for (name, ty) in m.args.iter().map(|a| (&a.name, ty_to_str(&a.ty))) {            @ty @name; json_get<@ty>(__data, "@name", @name);
 | 
			
		||||
@for (name, ty) in m.args.iter().map(|a| (&a.name, ty_to_str(&a.ty))) {            @ty @name; @name << json_get(__data, "@name");
 | 
			
		||||
            }
 | 
			
		||||
            @if m.ret_stream || m.ret.is_none() {@(s.name)_@(m.name)(@call_args(m));}
 | 
			
		||||
            else {send_msg(__c, @(s.name)_@(m.name)(@call_args(m)));}
 | 
			
		||||
@@ -31,10 +31,10 @@ enum struct @e.name : std::uint64_t @{
 | 
			
		||||
    @e.values.iter().map(|(k,v)| format!("{k} = {v}")).join(",\n    ")
 | 
			
		||||
@};
 | 
			
		||||
}
 | 
			
		||||
@for s in &rpc.structs {struct @s.name;
 | 
			
		||||
@for s in &rpc.structs {@get_struct_generics(s)struct @s.name;
 | 
			
		||||
}
 | 
			
		||||
@for s in &rpc.structs {
 | 
			
		||||
struct @s.name @{
 | 
			
		||||
@get_struct_generics(s)struct @s.name @{
 | 
			
		||||
@for f in &s.fields {    @ty_to_str(&f.ty) @f.name;
 | 
			
		||||
}
 | 
			
		||||
    MRPCJWriter& operator >>(MRPCJWriter&) const;
 | 
			
		||||
@@ -58,6 +58,7 @@ struct MRPCStream final : MRPCStreamImpl @{
 | 
			
		||||
@for s in streams_required(rpc) {template struct MRPCStream<@(s)>;
 | 
			
		||||
}}
 | 
			
		||||
struct MRPCServer @{
 | 
			
		||||
    MRPCServer() = delete;
 | 
			
		||||
    explicit MRPCServer(std::shared_ptr<restbed::Resource>&);
 | 
			
		||||
private:
 | 
			
		||||
@for s in &rpc.services {@for m in &s.methods {    virtual @method_ret(m) @(s.name)_@(m.name)(@method_args(m)) = 0;
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
@use crate::data::RPC;
 | 
			
		||||
@use crate::generators::cpp_s::*;
 | 
			
		||||
 | 
			
		||||
@(rpc: &RPC)
 | 
			
		||||
template<typename T>
 | 
			
		||||
void json_get(const rapidjson::Value &j, const char *key, T &v);
 | 
			
		||||
template<typename T>
 | 
			
		||||
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<typename T>
 | 
			
		||||
inline void json_get_inner(const rapidjson::Value &member, std::optional<T> &v) @{
 | 
			
		||||
    if (member.IsNull())
 | 
			
		||||
        v = std::nullopt;
 | 
			
		||||
    else @{
 | 
			
		||||
        T t;
 | 
			
		||||
        json_get_inner<T>(member, t);
 | 
			
		||||
        v = std::move(t);
 | 
			
		||||
    @}
 | 
			
		||||
@}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline void json_get_inner(const rapidjson::Value &member, std::vector<T> &v) @{
 | 
			
		||||
    if (!member.IsArray())
 | 
			
		||||
        throw std::exception@{@};
 | 
			
		||||
    for (const auto &j : member.GetArray()) @{
 | 
			
		||||
        T t;
 | 
			
		||||
        json_get_inner<T>(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<std::uint64_t>(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<typename T>
 | 
			
		||||
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; @}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								templates/cpp_server_json.rs.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								templates/cpp_server_json.rs.cxx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
@use crate::data::RPC;
 | 
			
		||||
@use crate::generators::cpp_s::*;
 | 
			
		||||
 | 
			
		||||
@(rpc: &RPC)
 | 
			
		||||
@for (ty, jty) in JSON_INNER_IMPLS {
 | 
			
		||||
inline @(ty)& operator<<(@ty &v, const rapidjson::Value &j) @{
 | 
			
		||||
    if (!j.Is@(jty)())
 | 
			
		||||
        throw std::exception@{@};
 | 
			
		||||
    v = j.Get@(jty)();
 | 
			
		||||
    return v;
 | 
			
		||||
@}
 | 
			
		||||
inline mrpc::MRPCJWriter& operator>>(const @ty &v, mrpc::MRPCJWriter &w) @{
 | 
			
		||||
    w.@(jty)(v);
 | 
			
		||||
    return w;
 | 
			
		||||
@}}
 | 
			
		||||
 | 
			
		||||
@for e in &rpc.enums {
 | 
			
		||||
inline mrpc::@e.name& operator<<(mrpc::@e.name &v, const rapidjson::Value &j) @{
 | 
			
		||||
    ((std::uint64_t&)v) << j;
 | 
			
		||||
    return v;
 | 
			
		||||
@}
 | 
			
		||||
mrpc::MRPCJWriter& operator>>(const mrpc::@e.name &v, mrpc::MRPCJWriter &w) @{
 | 
			
		||||
    w.Uint64((std::uint64_t)v);
 | 
			
		||||
    return w;
 | 
			
		||||
@}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline std::vector<T>& operator<<(std::vector<T> &v, const rapidjson::Value &j);
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline std::optional<T>& operator<<(std::optional<T> &v, const rapidjson::Value &j) @{
 | 
			
		||||
    if (j.IsNull())
 | 
			
		||||
        v = std::nullopt;
 | 
			
		||||
    else @{
 | 
			
		||||
        T t;
 | 
			
		||||
        t << j;
 | 
			
		||||
        v = std::move(t);
 | 
			
		||||
    @}
 | 
			
		||||
    return v;
 | 
			
		||||
@}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline std::vector<T>& operator<<(std::vector<T> &v, const rapidjson::Value &j) @{
 | 
			
		||||
    if (!j.IsArray())
 | 
			
		||||
        throw std::exception@{@};
 | 
			
		||||
    for (const auto &e : j.GetArray()) @{
 | 
			
		||||
        T t;
 | 
			
		||||
        t << e;
 | 
			
		||||
        v.push_back(std::move(t));
 | 
			
		||||
    @}
 | 
			
		||||
    return v;
 | 
			
		||||
@}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline mrpc::MRPCJWriter& operator>>(const std::vector<T> &v, mrpc::MRPCJWriter &w);
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline mrpc::MRPCJWriter& operator>>(const std::optional<T> &v, mrpc::MRPCJWriter &w) @{
 | 
			
		||||
    if (v.has_value())
 | 
			
		||||
        v.value() >> w;
 | 
			
		||||
    else
 | 
			
		||||
        w.Null();
 | 
			
		||||
    return w;
 | 
			
		||||
@}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
inline mrpc::MRPCJWriter& operator>>(const std::vector<T> &v, mrpc::MRPCJWriter &w) @{
 | 
			
		||||
    w.StartArray();
 | 
			
		||||
    for (const auto &e : v)
 | 
			
		||||
        e >> w;
 | 
			
		||||
    w.EndArray();
 | 
			
		||||
    return w;
 | 
			
		||||
@}
 | 
			
		||||
 | 
			
		||||
inline const rapidjson::Value& json_get(const rapidjson::Value &j, const char *key) @{
 | 
			
		||||
    auto member = j.FindMember(key);
 | 
			
		||||
    if (member == j.MemberEnd())
 | 
			
		||||
        throw std::exception@{@};
 | 
			
		||||
    return member->value;
 | 
			
		||||
@}
 | 
			
		||||
 | 
			
		||||
namespace mrpc @{
 | 
			
		||||
@for s in &rpc.structs {
 | 
			
		||||
@get_struct_generics(s)MRPCJWriter& @(s.name)@(generics_brace(s))::operator>>(MRPCJWriter &__w) const @{
 | 
			
		||||
    __w.StartObject();
 | 
			
		||||
@for f in &s.fields {    __w.Key("@f.name", @f.name.len());
 | 
			
		||||
    @f.name >> __w;
 | 
			
		||||
}    __w.EndObject();
 | 
			
		||||
    return __w;
 | 
			
		||||
@}
 | 
			
		||||
@get_struct_generics(s)@(s.name)@(generics_brace(s))& @(s.name)@(generics_brace(s))::operator<<(const rapidjson::Value &__j) @{
 | 
			
		||||
    using namespace mrpc;
 | 
			
		||||
@for f in &s.fields {    @f.name << json_get(__j, "@f.name");
 | 
			
		||||
}    return *this;
 | 
			
		||||
@}
 | 
			
		||||
}
 | 
			
		||||
@@ -10,7 +10,7 @@ export enum @e.name @{
 | 
			
		||||
}@}
 | 
			
		||||
}
 | 
			
		||||
@for s in &rpc.structs {
 | 
			
		||||
export interface @s.name @{
 | 
			
		||||
export interface @s.name@get_struct_generics(s) @{
 | 
			
		||||
@for f in &s.fields {    @f.name: @ty_to_str(&f.ty);
 | 
			
		||||
}@}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user