Commit be1d3de4 by Niels Lohmann Committed by Théo DELRIEU

💄 moved changes to re2c file and ran `make pretty`

parent aa2679a8
...@@ -38,67 +38,67 @@ using nlohmann::json; ...@@ -38,67 +38,67 @@ using nlohmann::json;
namespace udt namespace udt
{ {
enum class country enum class country
{ {
china, china,
france, france,
russia russia
}; };
struct age struct age
{ {
int m_val; int m_val;
}; };
struct name struct name
{ {
std::string m_val; std::string m_val;
}; };
struct address struct address
{ {
std::string m_val; std::string m_val;
}; };
struct person struct person
{ {
age m_age; age m_age;
name m_name; name m_name;
country m_country; country m_country;
}; };
struct contact struct contact
{ {
person m_person; person m_person;
address m_address; address m_address;
}; };
struct contact_book struct contact_book
{ {
name m_book_name; name m_book_name;
std::vector<contact> m_contacts; std::vector<contact> m_contacts;
}; };
} }
// to_json methods // to_json methods
namespace udt namespace udt
{ {
// templates because of the custom_json tests (see below) // templates because of the custom_json tests (see below)
template <typename Json> template <typename Json>
void to_json(Json& j, age a) void to_json(Json& j, age a)
{ {
j = a.m_val; j = a.m_val;
} }
template <typename Json> template <typename Json>
void to_json(Json& j, name const& n) void to_json(Json& j, name const& n)
{ {
j = n.m_val; j = n.m_val;
} }
template <typename Json> template <typename Json>
void to_json(Json& j, country c) void to_json(Json& j, country c)
{ {
switch (c) switch (c)
{ {
case country::china: case country::china:
...@@ -111,123 +111,128 @@ namespace udt ...@@ -111,123 +111,128 @@ namespace udt
j = u8"Российская Федерация"; j = u8"Российская Федерация";
return; return;
} }
} }
template <typename Json> template <typename Json>
void to_json(Json& j, person const& p) void to_json(Json& j, person const& p)
{ {
j = Json{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}}; j = Json{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}};
} }
void to_json(nlohmann::json& j, address const& a) void to_json(nlohmann::json& j, address const& a)
{ {
j = a.m_val; j = a.m_val;
} }
void to_json(nlohmann::json& j, contact const& c) void to_json(nlohmann::json& j, contact const& c)
{ {
j = json{{"person", c.m_person}, {"address", c.m_address}}; j = json{{"person", c.m_person}, {"address", c.m_address}};
} }
void to_json(nlohmann::json& j, contact_book const& cb) void to_json(nlohmann::json& j, contact_book const& cb)
{ {
j = json{{"name", cb.m_book_name}, {"contacts", cb.m_contacts}}; j = json{{"name", cb.m_book_name}, {"contacts", cb.m_contacts}};
} }
// operators // operators
bool operator==(age lhs, age rhs) bool operator==(age lhs, age rhs)
{ {
return lhs.m_val == rhs.m_val; return lhs.m_val == rhs.m_val;
} }
bool operator==(address const &lhs, address const &rhs) bool operator==(address const& lhs, address const& rhs)
{ {
return lhs.m_val == rhs.m_val; return lhs.m_val == rhs.m_val;
} }
bool operator==(name const &lhs, name const &rhs) bool operator==(name const& lhs, name const& rhs)
{ {
return lhs.m_val == rhs.m_val; return lhs.m_val == rhs.m_val;
} }
bool operator==(person const &lhs, person const &rhs) bool operator==(person const& lhs, person const& rhs)
{ {
return std::tie(lhs.m_name, lhs.m_age) == std::tie(rhs.m_name, rhs.m_age); return std::tie(lhs.m_name, lhs.m_age) == std::tie(rhs.m_name, rhs.m_age);
} }
bool operator==(contact const &lhs, contact const &rhs) bool operator==(contact const& lhs, contact const& rhs)
{ {
return std::tie(lhs.m_person, lhs.m_address) == return std::tie(lhs.m_person, lhs.m_address) ==
std::tie(rhs.m_person, rhs.m_address); std::tie(rhs.m_person, rhs.m_address);
} }
bool operator==(contact_book const &lhs, contact_book const &rhs) bool operator==(contact_book const& lhs, contact_book const& rhs)
{ {
return std::tie(lhs.m_book_name, lhs.m_contacts) == return std::tie(lhs.m_book_name, lhs.m_contacts) ==
std::tie(rhs.m_book_name, rhs.m_contacts); std::tie(rhs.m_book_name, rhs.m_contacts);
} }
} }
// from_json methods // from_json methods
namespace udt namespace udt
{ {
template <typename Json> template <typename Json>
void from_json(Json const& j, age &a) void from_json(Json const& j, age& a)
{ {
a.m_val = j.template get<int>(); a.m_val = j.template get<int>();
} }
template <typename Json> template <typename Json>
void from_json(Json const& j, name &n) void from_json(Json const& j, name& n)
{ {
n.m_val = j.template get<std::string>(); n.m_val = j.template get<std::string>();
} }
template <typename Json> template <typename Json>
void from_json(Json const &j, country &c) void from_json(Json const& j, country& c)
{ {
const auto str = j.template get<std::string>(); const auto str = j.template get<std::string>();
static const std::map<std::string, country> m = { static const std::map<std::string, country> m =
{
{u8"中华人民共和国", country::china}, {u8"中华人民共和国", country::china},
{"France", country::france}, {"France", country::france},
{"Российская Федерация", country::russia}}; {"Российская Федерация", country::russia}
};
const auto it = m.find(str); const auto it = m.find(str);
// TODO test exceptions // TODO test exceptions
c = it->second; c = it->second;
} }
template <typename Json> template <typename Json>
void from_json(Json const& j, person &p) void from_json(Json const& j, person& p)
{ {
p.m_age = j["age"].template get<age>(); p.m_age = j["age"].template get<age>();
p.m_name = j["name"].template get<name>(); p.m_name = j["name"].template get<name>();
p.m_country = j["country"].template get<country>(); p.m_country = j["country"].template get<country>();
} }
void from_json(nlohmann::json const &j, address &a) void from_json(nlohmann::json const& j, address& a)
{ {
a.m_val = j.get<std::string>(); a.m_val = j.get<std::string>();
} }
void from_json(nlohmann::json const& j, contact &c) void from_json(nlohmann::json const& j, contact& c)
{ {
c.m_person = j["person"].get<person>(); c.m_person = j["person"].get<person>();
c.m_address = j["address"].get<address>(); c.m_address = j["address"].get<address>();
} }
void from_json(nlohmann::json const&j, contact_book &cb) void from_json(nlohmann::json const& j, contact_book& cb)
{ {
cb.m_book_name = j["name"].get<name>(); cb.m_book_name = j["name"].get<name>();
cb.m_contacts = j["contacts"].get<std::vector<contact>>(); cb.m_contacts = j["contacts"].get<std::vector<contact>>();
} }
} }
TEST_CASE("basic usage", "[udt]") TEST_CASE("basic usage", "[udt]")
{ {
// a bit narcissic maybe :) ? // a bit narcissic maybe :) ?
const udt::age a{23}; const udt::age a
{
23
};
const udt::name n{"theo"}; const udt::name n{"theo"};
const udt::country c{udt::country::france}; const udt::country c{udt::country::france};
const udt::person sfinae_addict{a, n, c}; const udt::person sfinae_addict{a, n, c};
...@@ -295,18 +300,26 @@ struct adl_serializer<std::shared_ptr<T>> ...@@ -295,18 +300,26 @@ struct adl_serializer<std::shared_ptr<T>>
static void to_json(json& j, std::shared_ptr<T> const& opt) static void to_json(json& j, std::shared_ptr<T> const& opt)
{ {
if (opt) if (opt)
{
j = *opt; j = *opt;
}
else else
{
j = nullptr; j = nullptr;
} }
}
static void from_json(json const &j, std::shared_ptr<T> &opt) static void from_json(json const& j, std::shared_ptr<T>& opt)
{ {
if (j.is_null()) if (j.is_null())
{
opt = nullptr; opt = nullptr;
}
else else
{
opt.reset(new T(j.get<T>())); opt.reset(new T(j.get<T>()));
} }
}
}; };
template <> template <>
...@@ -387,7 +400,7 @@ struct adl_serializer<std::vector<T>> ...@@ -387,7 +400,7 @@ struct adl_serializer<std::vector<T>>
{ {
} }
static void from_json(json const &j, std::vector<T> &opt) static void from_json(json const& j, std::vector<T>& opt)
{ {
} }
}; };
...@@ -396,9 +409,9 @@ struct adl_serializer<std::vector<T>> ...@@ -396,9 +409,9 @@ struct adl_serializer<std::vector<T>>
TEST_CASE("current supported types are preferred over specializations", "[udt]") TEST_CASE("current supported types are preferred over specializations", "[udt]")
{ {
json j = std::vector<int>{1, 2, 3}; json j = std::vector<int> {1, 2, 3};
auto f = j.get<std::vector<int>>(); auto f = j.get<std::vector<int>>();
CHECK((f == std::vector<int>{1, 2, 3})); CHECK((f == std::vector<int> {1, 2, 3}));
} }
namespace nlohmann namespace nlohmann
...@@ -409,20 +422,28 @@ struct adl_serializer<std::unique_ptr<T>> ...@@ -409,20 +422,28 @@ struct adl_serializer<std::unique_ptr<T>>
static void to_json(json& j, std::unique_ptr<T> const& opt) static void to_json(json& j, std::unique_ptr<T> const& opt)
{ {
if (opt) if (opt)
{
j = *opt; j = *opt;
}
else else
{
j = nullptr; j = nullptr;
} }
}
// this is the overload needed for non-copyable types, // this is the overload needed for non-copyable types,
// should we add a priority tag in the implementation to prefer this overload if it exists? // should we add a priority tag in the implementation to prefer this overload if it exists?
static std::unique_ptr<T> from_json(json const &j) static std::unique_ptr<T> from_json(json const& j)
{ {
if (j.is_null()) if (j.is_null())
{
return nullptr; return nullptr;
}
else else
{
return std::unique_ptr<T>(new T(j.get<T>())); return std::unique_ptr<T>(new T(j.get<T>()));
} }
}
}; };
} }
...@@ -477,7 +498,9 @@ struct pod_serializer ...@@ -477,7 +498,9 @@ struct pod_serializer
auto bytes = static_cast<char const*>(static_cast<void const*>(&t)); auto bytes = static_cast<char const*>(static_cast<void const*>(&t));
std::uint64_t value = bytes[0]; std::uint64_t value = bytes[0];
for (auto i = 1; i < 8; ++i) for (auto i = 1; i < 8; ++i)
{
value |= bytes[i] << 8 * i; value |= bytes[i] << 8 * i;
}
j = value; j = value;
} }
...@@ -514,7 +537,7 @@ TEST_CASE("custom serializer for pods", "[udt]") ...@@ -514,7 +537,7 @@ TEST_CASE("custom serializer for pods", "[udt]")
template <typename T, typename> template <typename T, typename>
struct another_adl_serializer; struct another_adl_serializer;
using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>; using custom_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, another_adl_serializer>;
template <typename T, typename> template <typename T, typename>
struct another_adl_serializer struct another_adl_serializer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment