mercredi 1 juillet 2020

Extension plans for formatting of trivial structs in C++ fmtlib?

In my current project I need a custom very simple "serialized" representation of a couple of trivial DTO structures. After first coming up with a custom made solution, that was a big PITA, I had the idea to use FMTlib for that.

So the last days I was playing around with formatting of custom types via extensions of the fmt::formatter template specialization mechanism. Therefore this blog and your docs were very helpful.

After a little bit of fiddling around, I came up with a pretty generic poc solution, that allows to format structures in multiple custom formats, that looks a little bit like the following:

struct Inner {
    double x;
    std::string y;
    int z;
};
struct Outer {
    int a;
    std::string b;
    Inner inner;
};

template<>
struct reflection<Outer> {
    /*definition of class name and field names has to be provided manually...*/
};

template<>
struct reflection<Inner> {
    /*definition of class name and field names has to provided manually...*/
};

/*
...
couple dozend lines of meta programming and fmt::formatter specializations.
...
*/

auto outer = Outer{.a=1,.b="hello",.inner={.x=3.12,.y=" ",.z=2}};

std::string simple = fmt::format("{:s}", outer); // :s means format as simple
assert(simple == "a|hello|3.12| |2");
assert(fmt::format("{:s;}", outer) == "a;hello;3.12; ;2");

std::string  extended = fmt::format("{:e}",outer); // :e means format as extended
assert(extended == "Outer{.a=1, .b=hello, .inner=Inner{.x=3.12, .y= , .z=2}}");

Obviously, there is no standard way to reflect about the fields and the name of a structure, so the reflection structure has to be provided either manually, or e.g. via macros-magic. But that is a different topic that I don't want to address here. - If we are lucky we get some minimal compile time reflection in c++23 \o/. Let's hope!

I put all this together in this repo.

The actual question:

Would formatting user defined types via a simple reflection API provided by libfmt be something that you'd consider a possible future extension to fmtlib? I imagine a scenario, where a couple of trivial formatting patterns are predefined, and the user only has to provide the reflection for his types.

With this, I can even see formatting expessions like fmt::format("{:json,prety,tabwith=4}", outer) on the horizon.

Also, maybe I'm just reinventing the wheel, so if there is something like this, based on fmtlib out there - tell me! :)

Anyway, thanks for providing your awesome tool to the community and congrats to making it into c++20!

Regards, Martin





Aucun commentaire:

Enregistrer un commentaire