TheNitesWhoSay / RareCpp

Creating a simpler, more intuitive means of C++ reflection

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] How to map DTO to a C++ gRPC/ProtoBuf Object Because it is final and has accessor functions!)

Smurf-IV opened this issue · comments

I have the following DTO:

struct TargetVersionInfoV24Out
{
    int32_t major;
    int32_t minor;
    int32_t build;
    int32_t patch;
    std::string special_text;

    REFLECT(TargetVersionInfoV24Out, Major, Minor, Build, Patch, SpecialText)
} out;

And there is an equivalent gRPC Reply built from a message with the similar fields.
But I cannot use the Proxy method because:

  • the ProtoBuf class is created as final (via protoc)
  • The access to the fields has to be via accessor functions e.g.:
    • response->set_major(out.major);
    • etc. then
    • response->set_special_text(out.special_text);

So, I would like to create an external reflection from DTO into the ProtoBuf response, How ?

Good morning, on a basic design level RareCpp's reflection is based on having references to data members (e.g. the value & being iterated here), and I can't turn a (normal) getter and setter into data reference.

If you faithfully reproduced the data layout for the target class, you may be able to simply alias it, this is ofc UB and not guaranteed to play nicely on every system/in every situation, but it usually works if the two classes data layouts are the same.

Alternatively you can create a mapping between the two types using map_to/map_from (which you could do manually or with less work using a custom reflect macro that generates these methods for you) - this isn't the same as adding reflection to a type, rather it just enables easily copying between them (and doing so automatically behind the scenes for JSON), but that's sufficient for some use-cases.

In the future I may add the capability to reflect private members, but sorry I can't suggest a more ideal solution today; hope this helps!

You can now reflect private members, if reflecting the private data members behind these data members works for you then this is as simple as https://godbolt.org/z/4sv41bT7b .

If you're not comfortable binding to private data members this way you can also use this new means of reflection to bind your public getter/setter functions and use reflection capabilities on those e.g. https://godbolt.org/z/q931j9d4E; though as far as my plans go I won't be adding any "first-class" support to getter and setters (e.g. json won't work automagically).

Going to close this issue but feel free to reopen if you wish to discuss further.