-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to parse json file with type composition of std::optional and std::variant #1910
Comments
I do not fully understand your goal. What do you want to achieve after parsing the JSON above? Convert it to a certain type? |
there is an interesting take using Unfortunately I have not found a way to make it work in my local. |
How should the C++ type where you want to parse to look like? |
@nlohmann The c++ type should look like this: https://github.com/chakpongchung/catchThemAll/blob/master/Main.hs Or as c++ code in the following:
@dota17 Please take a closer look of this part I can do it in Haskell and Scala but still wanna know whether I can find a json library in C++ supporting this. |
compositional type
of optional
and variant
compositional type
of optional
and variant
optional
and variant
optional
and variant
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
@chakpongchung The data types you mentioned like |
I looked at the comment suggested. I dont see why it is solving the problem of mixing optional and variant. |
@chakpongchung Do you still need assistance on this? |
Yes, my question is still not addressed properly. The other issue mentioned is not close to what I am after. I am looking for support of std::optional<variant<a,b,c>> to parse the list of jsons which can contain different types in certain properties. @nlohmann |
What about #include <iostream>
#include <optional>
#include <variant>
#include "json.hpp"
using json = nlohmann::json;
// partial specialization (full specialization works too)
namespace nlohmann {
template <typename T>
struct adl_serializer<std::optional<T>> {
static void to_json(json& j, const std::optional<T>& opt) {
if (opt == std::nullopt) {
j = nullptr;
} else {
j = *opt;
}
}
static void from_json(const json& j, std::optional<T>& opt) {
if (j.is_null()) {
opt = std::nullopt;
} else {
opt = j.get<T>();
}
}
};
}
struct Boosts {
std::optional<int> atk;
std::optional<int> def;
};
void to_json(json& j, const Boosts& b)
{
j["atk"] = b.atk;
j["def"] = b.def;
}
struct Self {
std::optional<Boosts> boosts;
};
void to_json(json& j, const Self& s)
{
j["boosts"] = s.boosts;
}
struct Secondary {
std::optional<int> chance;
std::optional<std::string> volatileStatus;
std::optional<Boosts> boosts;
std::optional<Self> self;
std::optional<std::string> status;
};
void to_json(json& j, const Secondary& s)
{
j["chance"] = s.chance;
j["volatileStatus"] = s.volatileStatus;
j["boosts"] = s.boosts;
j["self"] = s.self;
j["status"] = s.status;
}
struct move_t {
int num;
std::variant<bool, int> accuracy;
int basePower;
std::string category;
std::optional<std::string> desc = std::nullopt;
std::string shortDesc;
std::string id;
std::string name;
std::optional<std::variant<bool, Secondary>> secondary;
};
void to_json(json& j, const move_t& m)
{
j["num"] = m.num;
switch(m.accuracy.index())
{
case 0:
j["accuracy"] = std::get<bool>(m.accuracy);
break;
case 1:
j["accuracy"] = std::get<int>(m.accuracy);
break;
}
j["basePower"] = m.basePower;
j["category"] = m.category;
j["desc"] = m.desc;
j["shortDesc"] = m.shortDesc;
j["id"] = m.id;
j["name"] = m.name;
if (m.secondary.has_value())
{
switch(m.secondary.value().index())
{
case 0:
j["secondary"] = std::get<bool>(m.secondary.value());
break;
case 1:
j["secondary"] = std::get<Secondary>(m.secondary.value());
break;
}
}
else
{
j["secondary"] = nullptr;
}
}
int main() {
Boosts b;
b.atk = 1;
Self s;
s.boosts = b;
Secondary sec;
sec.boosts = b;
sec.self = s;
move_t m;
m.secondary = sec;
m.accuracy = 10;
std::cout << json(m).dump(2) << std::endl;
} prints {
"accuracy": 10,
"basePower": 0,
"category": "",
"desc": null,
"id": "",
"name": "",
"num": 0,
"secondary": {
"boosts": {
"atk": 1,
"def": null
},
"chance": null,
"self": {
"boosts": {
"atk": 1,
"def": null
}
},
"status": null,
"volatileStatus": null
},
"shortDesc": ""
} |
I think it is much closer now, except that you are hand crafting some inputs. https://github.com/pokeai/pokeai And I also wonder why in c++ we need to add switch case in the |
Is there anything left to do here? |
Yes, I tried your code and use it to parse the json which is a list of
|
Where does the error occur? What does it say? |
The error message is not so indicative and it starts from this line:
|
In the code above, only the conversion to JSON was defined. If you want to read from a JSON value, you need to define the respective |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
@dubnde @nlohmann
This is related to the following issues, perhaps think of this question and the json file as a test case for parsing compositional type of
optional
andvariant
(seesecondary
field from the full json input below):#1281
#1261 (comment)
How I can parse the input json inside this file ?
https://github.com/smogon/pokemon-showdown/blob/master/data/moves.js
For the
secondary
andflags
properties? They aretype composition
ofstd::optional
andstd::variant
.Though only the full example can surface the problem in a clearer way, a minimal starting point example would be this one for the impatient:
The expected output can be but not limited to:
For your convenience, you can attach this snippet to the end of the js file and run it using
node move.js
. Two valid json files will be saved to your disk. One is a list of json objects while the other is an object with string as key.In c++(17/20), there are previous attempts here:
#1281
#1910
#1261 (comment)
Here is a boiler plate with the type
move_t
I would like to use that you can begin with:Could you provide an example to parse this full json file?
The text was updated successfully, but these errors were encountered: