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