-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
- 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;
}-
What is the expected behavior?
Am able to convert json to custom type -
And what is the actual behavior instead?
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
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