- What is the issue you have?
I'm trying to reduce the level of nesting in my output JSON. I can do this fine by converting my type directly to a string, rather than giving the single member variable a name, for example:
void to_json(json &j, const PublicKey &s)
{
/* .data is an array of uint8_t, podToHex converts to a hex string */
j = Common::podToHex(s.data);
}
instead of
void to_json(json &j, const PublicKey &s)
{
j = {"publicKey", Common::podToHex(s.data)};
}
This works fine, and in my usage this function gets used to convert a std::unordered_set to json. Here's an example json output I get:
"keyImages": [
"0682b576d89456a958c496a5e053deddf96645b3a9a5f371e160e0ce66d98ecb",
"145c1153ad0040a3bf24b0e96bd8c39e216cce785782fd1d7fec67ad483fbb4b",
"8285716e53853663ba1fa02d977a10181543541e2f13bba983994e98f45cfbee",
"f436604c007c4fca61a7d5ad474051ec2d66cd75856ef209b02106ba9bd10a36",
"6ab7fb46e729fc707966776203d955e6afa90f527aae7bed5cda121d782fd9ee",
"bf2c60b78877115bff86b90d6c5d689832ec4697ef8984f44f2cfa6dc5f3d90d"
],
Now however, I'm not sure how to convert this JSON back into my type. The type is a std::unordered_set. Previously, I was giving a data name to each array element, so my from_json looked like -
void from_json(const json &j, PublicKey &s)
{
std::string hash = j.at("publicKey").get<std::string>();
/* Converts from string to uint8_t array */
Common::podFromHex(hash, s.data);
}
However, this cannot work if we are not storing the key name. How can we implement our from_json function without having a key name to at()?
- Please describe the steps to reproduce the issue. Can you provide a small but working code example?
#include "json.hpp"
#include <unordered_set>
using nlohmann::json;
void podFromHex(const uint8_t *data, std::string hash)
{
/* Completely horrible simple implementation for example purposes */
data = reinterpret_cast<const uint8_t *>(hash.c_str());
}
struct PublicKey
{
uint8_t data[32];
inline bool operator==(const PublicKey &other) const
{
return std::memcmp(this->data, other.data, sizeof(PublicKey::data)) == 0;
}
};
namespace std
{
template<>
struct hash<PublicKey>
{
size_t operator()(const PublicKey &p) const
{
return reinterpret_cast<const size_t &>(p);
}
};
}
struct Wallet
{
std::unordered_set<PublicKey> keyImages;
uint64_t balance;
};
void from_json(const json &j, Wallet &w)
{
w.balance = j.at("balance").get<uint64_t>();
w.keyImages = j.at("keyImages").get<std::unordered_set<PublicKey>>();
}
void from_json(const json &j, PublicKey &p)
{
/* What should this be?
std::string hash = j.at("???").get<std::string>();
*/
std::string hash;
podFromHex(p.data, hash);
}
int main()
{
json j = {
{"balance", 100},
{"keyImages", {
"0682b576d89456a958c496a5e053deddf96645b3a9a5f371e160e0ce66d98ecb",
"145c1153ad0040a3bf24b0e96bd8c39e216cce785782fd1d7fec67ad483fbb4b",
"8285716e53853663ba1fa02d977a10181543541e2f13bba983994e98f45cfbee"
}}
};
Wallet w = j;
}
terminate called after throwing an instance of 'nlohmann::detail::type_error'
what(): [json.exception.type_error.304] cannot use at() with string
-
Which compiler and operating system are you using? Is it a supported compiler?
Compiler: g++ 8.2.1
OS: Linux 4.18.9
-
Did you use a released version of the library or the version from the develop branch?
Using the released version, v3.2.0
-
If you experience a compilation error: can you compile and run the unit tests?
N/A
edit - Of course I could just use a function and loop through the data, but I'd prefer a solution where I don't need to have a function for each standard container type which already has support built in
I'm trying to reduce the level of nesting in my output JSON. I can do this fine by converting my type directly to a string, rather than giving the single member variable a name, for example:
instead of
This works fine, and in my usage this function gets used to convert a std::unordered_set to json. Here's an example json output I get:
Now however, I'm not sure how to convert this JSON back into my type. The type is a std::unordered_set. Previously, I was giving a data name to each array element, so my from_json looked like -
However, this cannot work if we are not storing the key name. How can we implement our from_json function without having a key name to at()?
What is the expected behavior?
Am able to convert json to custom type
And what is the actual behavior instead?
Which compiler and operating system are you using? Is it a supported compiler?
Compiler: g++ 8.2.1
OS: Linux 4.18.9
Did you use a released version of the library or the version from the
developbranch?Using the released version, v3.2.0
If you experience a compilation error: can you compile and run the unit tests?
N/A
edit - Of course I could just use a function and loop through the data, but I'd prefer a solution where I don't need to have a function for each standard container type which already has support built in