Deserializing json into a general struct #130
-
hi! Is it possible to somehow read in json without providing the struct+bindings (perhaps reading it in as some kind of an unordered_map)? I am migrating from Thanks for the help! |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 2 replies
-
std::variant support exists, but it currently doesn't deduce the type from the JSON. This is intentional, for performance reasons and to encourage working directly with C++ types. If you know nothing about the JSON and purely want to query what it contains, then libraries like Generic writing is easily supported as this example shows: std::map<std::string, std::variant<std::string, int, bool>> request; // or std::unordered_map
request["username"] = "paulo";
request["password"] = "123456";
request["remember"] = true;
auto str = glz::write_json(request);
expect(str == R"({"password":"123456","remember":true,"username":"paulo"})"); Could you give a small example of what you are trying to achieve with generic reading? We are looking at automatic type deduction for The fact is that once you write code to query a specific item, you are expressing that you know the expected structure. But, we do realize it can be painful to define all these potential structures and sometimes a generic library like |
Beta Was this translation helpful? Give feedback.
-
Indeed I know exactly what I am receiving! I have two use cases for this:
Based on this data, I create the whole object. Is there a way to read this partial data? EDIT: Solved 2. with:
|
Beta Was this translation helpful? Give feedback.
-
Great, thanks for the clarification: Case 1: When you have multiple types with similar data, Glaze supports variant type deduction for custom objects. Case 2: Your solution is fine, but if you wanted your "number" to actually be a number and not a std::string, then this would require variant type deduction for basic types, which I had mentioned we were considering adding. So, I'll keep this example in mind. |
Beta Was this translation helpful? Give feedback.
-
Glaze has typically focused on strongly typed data, But I was thinking about this recently and with some modifications to how variant support works we should be able to handle completely generic json. I support this and don't think it'll be that hard to add. |
Beta Was this translation helpful? Give feedback.
-
@klemenpeganc, Just added a very basic generic json type glz::json_t (glaze/json/json_t.hpp) in #132 glz::json_t json{};
std::string buffer = R"([5,"Hello World",{"pi":3.14}])";
glz::read_json(json, buffer);
assert(json[0].get<double>() == 5.0);
assert(json[1].get<std::string>() == "Hello World");
assert(json[2]["pi"].get<double>() == 3.14); You can use it by itself or nested within one of your own meta objects or in a container. I would recommend using typed JSON like variants if possible but this offers a way to handle things when thats not possible. As pointed out by @stephenberry your example use case of having 3 structs (structA, structB, structC) is probably better handled by using std::variant as detailed here https://github.com/stephenberry/glaze/wiki/Variant-Handling#objects. Right now this depends on a type key when you have multiple object types but perhaps we might add a way for uses to inject their own methodology to deduce types but I can't think of a clean way to do that. Edit: glz::json_t json = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {{"everything", 42.0}}},
{"list", {1.0, 0.0, 2.0}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
}; Or this: glz::json_t json;
json["pi"] = 3.14;
json["happy"] = true;
json["name"] = "Niels";
json["nothing"] = nullptr;
json["answer"]["everything"] = 42.0;
json["list"] = { 1.0, 0.0, 2.0 };
json["object"] = { {"currency", "USD"}, {"value", 42.99} }; |
Beta Was this translation helpful? Give feedback.
@klemenpeganc, Just added a very basic generic json type glz::json_t (glaze/json/json_t.hpp) in #132
You can use it by itself or nested within one of your own meta objects or in a container. I would recommend using typed JSON like variants if possible but this offers a way to handle things when thats not possible.
As pointed out by @stephenberry your example use case of having 3 structs (structA, structB, structC) is probably better handled by using …