Replies: 9 comments
-
|
To get the same JSON output, you would need your types to be structs, because your JSON has objects. Here is code that would give you the same JSON: #include <iostream>
#include "glaze/glaze.hpp"
struct foo1_t {
std::string foo1{};
};
struct foo2_t {
std::string foo2{};
};
struct foo3_t {
int32_t foo3{};
};
using Foo = std::variant<foo1_t, foo2_t, foo3_t>;
struct Bar
{
std::vector<Foo> foos{ foo1_t{"bar"}, foo2_t{"bar"}, foo3_t{42} };
};
int main() {
Bar bar{};
std::cout << glz::write_json(bar) << '\n';
return 0;
}Also, a compiler explorer link: https://gcc.godbolt.org/z/5WPocsq3d |
Beta Was this translation helpful? Give feedback.
-
|
Glaze can auto-deduce the variant type because the fields have different names. Let me know if this works for you, or if you need a different solution. |
Beta Was this translation helpful? Give feedback.
-
|
That does work in that case, but what about just a field? struct Foo {
AnotherType foo;
std::variant<MyInt, MyInt2, MyString> var1;
};and I would want this to turn into json strings like this: {"foo":{"field1":1},"myInt":1}
{"foo":{"field1":1},"myString":"ba5eba11"}I initially was thinking of this, but simplified my initial example too much. An array stripped the name, that was hiding my difficulty. I could rewrite it that the entire Foo is duplicated with the differentiation being the name of the field that's swapped. I'm not sure if that would work nor if that's going to perform well. |
Beta Was this translation helpful? Give feedback.
-
|
What I meant was that I may be able to write it like this: struct FooWithInt1 {AnotherType foo; int myInt;};
struct FooWithInt2 {AnotherType foo; int myInt2;};
struct FooWithString {AnotherType foo; std::string myString;};
using Foo = std::variant<FooWithInt1, FooWithInt2, FooWithString>;But again, I hope there's a more graceful way |
Beta Was this translation helpful? Give feedback.
-
|
I'm a bit confused as to what you want to be able to write in C++. Could you give an example of how you want your C++ code to appear? Usually, you would tag your types, so that a tag like Tagging a variant is done like: template <>
struct glz::meta<Foo>
{
static constexpr auto ids = std::array{"FooWithInt1", "FooWithInt2", "FooWithString"};
}; |
Beta Was this translation helpful? Give feedback.
-
|
Firstly the usecase is actually to create a specific json that complies with a schema I got. {"foo":{"field1":1},"myInt":1}{"foo":{"field1":1},"myString":"ba5eba11"}{"foo":{"field1":1},"myInt2":42}I preferably just have the one variant field in my struct with other fields next to it. struct Foo {
AnotherType foo;
std::variant<MyInt, MyInt2, MyString> var1;
};But I want the json to ignore that the var1 is a separate field with objects inside of it and use the only field in that object to appear as the field in place of var1. Like I said, I was able to do it with the above code in my previous post, but I just don't like the duplication. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for this, I see your problem clearly now. What you're wanting is not currently supported, but I do think it may be worth adding. We can add support to use the type names in the Would adding this support work for you? Glaze allows you to rename your types as seen in JSON, so you could customize the keys in this manner. |
Beta Was this translation helpful? Give feedback.
-
|
That would indeed work just fine. It doesn't have a high priority, since I'm merely experimenting with glaze for future use (We're transitioning to c++20 from 17 soon (tm)). Thanks for the response. |
Beta Was this translation helpful? Give feedback.
-
|
I'm moving this to discussions as I don't think this will be supported any time soon. I've been improving variant handling and looked over this issue again, but I don't feel confident that my current approach would be generic enough for the long term. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I've got a use case where a target API expects a json string with one of a set of fields (a oneof field)
As an example the protobuf equivalent would be:
Which with protobuf's serializer would spawn the following json outputs:
{"foos":[{"foo1": "bar"},{"foo2": "bar"},{"foo3":42}]}I would like to represent this with a variant as follows:
To me that would make the most sense as opposed to 3 optionals or one field next to it that defines what type the field next to it is (like in the current example of tagged variants: https://github.com/stephenberry/glaze/blob/main/docs/variant-handling.md#deduction-of-tagged-object-types)
But it's not clear from the documentation whether this is supported or how to do this. Is it unsupported without elaborate boilerplate code?
Beta Was this translation helpful? Give feedback.
All reactions